diff --git a/src/client/Client.ts b/src/client/Client.ts index e55ae32..5a6e8eb 100644 --- a/src/client/Client.ts +++ b/src/client/Client.ts @@ -19,7 +19,7 @@ import { ChannelCredentials } from '@grpc/grpc-js'; import { RuntimeClient } from '../../proto/runtime/v1/runtime_grpc_pb'; import { ObjectStorageServiceClient } from '../../proto/extension/v1/s3/oss_grpc_pb'; import { CryptionServiceClient } from '../../proto/extension/v1/cryption/cryption_grpc_pb'; -import { State } from './State'; +import { State, StateOptions } from './State'; import { Hello } from './Hello'; import { Invoker } from './Invoker'; import { Lock } from './Lock'; @@ -112,7 +112,7 @@ export class Client { get state() { if (!this._state) { - this._state = new State(this._runtime, this.initAPIOptions); + this._state = new State(this._runtime, {}, this.initAPIOptions); } return this._state; } @@ -184,6 +184,13 @@ export class Client { return new Oss(ossClient, options, this.initAPIOptions); } + /** + * Create new state client instance + */ + createStateClient(options?: StateOptions) { + return new State(this._runtime, options, this.initAPIOptions); + } + get cryption() { if (!this._cryption) { if (!this._cryptionClient) { diff --git a/src/client/State.ts b/src/client/State.ts index 91e6c67..f3d7794 100644 --- a/src/client/State.ts +++ b/src/client/State.ts @@ -38,8 +38,27 @@ import { StateItem, } from '../types/State'; import { isEmptyPBMessage, convertMapToKVString } from '../utils'; +import { RuntimeClient } from '../../proto/runtime/v1/runtime_grpc_pb'; +import { APIOptions } from './API'; +import { RequestWithMeta } from '../types/common'; + +export interface StateOptions { + // set default metadata on every request + defaultRequestMeta?: Record; +} export class State extends RuntimeAPI { + #defaultRequestMeta?: Record; + + constructor(runtime: RuntimeClient, options?: StateOptions, apiOptions?: APIOptions) { + super(runtime, apiOptions); + this.#defaultRequestMeta = options?.defaultRequestMeta; + } + + createMetadata(request: RequestWithMeta<{}>) { + return super.createMetadata(request, this.#defaultRequestMeta); + } + // Saves an array of state objects async save(request: SaveStateRequest): Promise { let states = request.states; diff --git a/test/unit/client/State.test.ts b/test/unit/client/State.test.ts index 5e673eb..b1863d2 100644 --- a/test/unit/client/State.test.ts +++ b/test/unit/client/State.test.ts @@ -198,4 +198,32 @@ describe('client/State.test.ts', () => { // assert.equal(states.length, 20); }); }); + + describe('createStateClient()', () => { + it('should create a new state client success', async () => { + const key = 'js-sdk-unit-' + Date.now(); + const stateClient = client.createStateClient({ + defaultRequestMeta: { + foo: 'bar', + }, + }); + const value = `hello js-sdk, with δΈ­ζ–‡, πŸ˜„, at ${Date()}`; + await stateClient.save({ + storeName, + states: { key, value }, + requestMeta: { traceid: `mock-traceid-unittest-${Date.now()}` }, + }); + const state = await stateClient.get({ storeName, key }); + assert(state); + assert.equal(Buffer.from(state.value).toString(), value); + + await stateClient.save({ + storeName, + states: { key, value }, + }); + const state2 = await stateClient.get({ storeName, key }); + assert(state2); + assert.equal(Buffer.from(state2.value).toString(), value); + }); + }); });