@xyo-network/diviner-stateful 3.5.2 → 3.6.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"DivinerMixin.d.ts","sourceRoot":"","sources":["../../src/DivinerMixin.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,YAAY,EACZ,WAAW,EACX,eAAe,EAChB,MAAM,2BAA2B,CAAA;AAMlC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AAE1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAExD,MAAM,MAAM,oBAAoB,GAAG,YAAY,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAAA;AAGvF,MAAM,MAAM,SAAS,CAAC,OAAO,SAAS,oBAAoB,GAAG,oBAAoB,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,cAAc,CAAC,OAAO,CAAC,CAAA;AAIpI;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,OAAO,SAAS,oBAAoB;;;;;;;;;;;;;;;;;;;;;GACpC,OAAO,SAAS,SAAS,CAAC,OAAO,CAAC,uBAClC,MAAM,SAAS,eAAe,gCAElB,OAAO,6BAd8E,GAAG,EAAE;iBAiBvF,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAE1C;;;;;;OAMG;2BAC0B,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAU1D;;;;OAIG;;yBAqFwoC,4BAA4B;;mCAAmG,4BAA4B;;uBAAmF,4BAA4B,wBAAwB,4BAA4B,8BAA8B,2BAA2B,iCAAiC,2BAA2B,8BAA8B,4BAA4B,wBAAwB,4BAA4B,8BAA8B,2BAA2B,iCAAiC,2BAA2B;mBAA4C,CAAC,SAAS,8BAAa;6BAAiD,CAAC;;mBAAkF,CAAC,SAAS,8BAAa;4BAAgD,CAAC;;;;;;;8CAAsP,2BAA2B;;;;IA5Ej0E;;;;OAIG;;yBAwE+L,4BAA4B;;mCAAmG,4BAA4B;;uBAAmF,4BAA4B,wBAAwB,4BAA4B,8BAA8B,2BAA2B,iCAAiC,2BAA2B,8BAA8B,4BAA4B,wBAAwB,4BAA4B,8BAA8B,2BAA2B,iCAAiC,2BAA2B;;;;;;;;8CAAoT,2BAA2B;;;;;;;;;;;;;;;;;;;;;;IA5DvqC;;;;OAIG;;yBAwD+L,4BAA4B;;mCAAmG,4BAA4B;;uBAAmF,4BAA4B,wBAAwB,4BAA4B,8BAA8B,2BAA2B,iCAAiC,2BAA2B,8BAA8B,4BAA4B,wBAAwB,4BAA4B,8BAA8B,2BAA2B,iCAAiC,2BAA2B;;;;;;;;8CAAoT,2BAA2B;;;;;;;;;;;;;;;;;;;;;;IA/CvqC;;;OAGG;qBACoB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;;;;;;;;;;sRAvFhC,CAAC,6DAElC,CAAC;4RAGiB,CAAC,6DAAwB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBApBf,CAAC,yBACtC,CAAC;2FAMI,CAAC,yBACV,CAAC;;;;;;;;;;;;YAwIA,CAAA"}
1
+ {"version":3,"file":"DivinerMixin.d.ts","sourceRoot":"","sources":["../../src/DivinerMixin.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ var StatefulDivinerConfigSchema = `${StatefulDivinerSchema}.config`;
9
9
 
10
10
  // src/Diviner.ts
11
11
  import { assertEx } from "@xylabs/assert";
12
+ import { toJson } from "@xylabs/object";
12
13
  import { ArchivistWrapper } from "@xyo-network/archivist-wrapper";
13
14
  import { BoundWitnessBuilder } from "@xyo-network/boundwitness-builder";
14
15
  import { isBoundWitness } from "@xyo-network/boundwitness-model";
@@ -17,6 +18,7 @@ import { BoundWitnessDivinerQuerySchema } from "@xyo-network/diviner-boundwitnes
17
18
  import { DivinerWrapper } from "@xyo-network/diviner-wrapper";
18
19
  import { isModuleState, ModuleStateSchema } from "@xyo-network/module-model";
19
20
  import { PayloadBuilder } from "@xyo-network/payload-builder";
21
+ import { SequenceConstants } from "@xyo-network/payload-model";
20
22
  var moduleName = "StatefulDiviner";
21
23
  var StatefulDiviner = class extends AbstractDiviner {
22
24
  static {
@@ -39,7 +41,7 @@ var StatefulDiviner = class extends AbstractDiviner {
39
41
  * @param nextState The state to commit
40
42
  */
41
43
  async commitState(nextState) {
42
- if (nextState.state.offset === this._lastState?.state.offset) return;
44
+ if (toJson(nextState.state) === toJson(this._lastState?.state)) return;
43
45
  this._lastState = nextState;
44
46
  const archivist = await this.getArchivistForStateStore();
45
47
  const [bw] = await new BoundWitnessBuilder().payload(nextState).signer(this.account).build();
@@ -91,7 +93,7 @@ var StatefulDiviner = class extends AbstractDiviner {
91
93
  }).fields({
92
94
  address: this.account.address,
93
95
  limit: 1,
94
- offset: 0,
96
+ cursor: SequenceConstants.minLocalSequence,
95
97
  order: "desc",
96
98
  payload_schemas: [
97
99
  ModuleStateSchema
@@ -124,6 +126,7 @@ var StatefulDiviner = class extends AbstractDiviner {
124
126
 
125
127
  // src/DivinerMixin.ts
126
128
  import { assertEx as assertEx2 } from "@xylabs/assert";
129
+ import { toJson as toJson2 } from "@xylabs/object";
127
130
  import { asArchivistInstance } from "@xyo-network/archivist-model";
128
131
  import { BoundWitnessBuilder as BoundWitnessBuilder2 } from "@xyo-network/boundwitness-builder";
129
132
  import { isBoundWitness as isBoundWitness2 } from "@xyo-network/boundwitness-model";
@@ -131,6 +134,7 @@ import { BoundWitnessDivinerQuerySchema as BoundWitnessDivinerQuerySchema2 } fro
131
134
  import { asDivinerInstance } from "@xyo-network/diviner-model";
132
135
  import { isModuleState as isModuleState2, ModuleStateSchema as ModuleStateSchema2 } from "@xyo-network/module-model";
133
136
  import { PayloadBuilder as PayloadBuilder2 } from "@xyo-network/payload-builder";
137
+ import { SequenceConstants as SequenceConstants2 } from "@xyo-network/payload-model";
134
138
  var moduleName2 = "StatefulModuleMixin";
135
139
  var StatefulModuleMixin = /* @__PURE__ */ __name((ModuleBase) => {
136
140
  let StatefulModuleBase = class StatefulModuleBase extends ModuleBase {
@@ -146,7 +150,7 @@ var StatefulModuleMixin = /* @__PURE__ */ __name((ModuleBase) => {
146
150
  * @param nextState The state to commit
147
151
  */
148
152
  async commitState(nextState) {
149
- if (nextState.state.offset === this._lastState?.state.offset) return;
153
+ if (toJson2(nextState.state) === toJson2(this._lastState?.state)) return;
150
154
  this._lastState = nextState;
151
155
  const archivist = await this.getArchivistForStore();
152
156
  const [bw] = await (await new BoundWitnessBuilder2().payload(nextState)).build();
@@ -201,7 +205,7 @@ var StatefulModuleMixin = /* @__PURE__ */ __name((ModuleBase) => {
201
205
  }).fields({
202
206
  // address: this.account.address,
203
207
  limit: 1,
204
- offset: 0,
208
+ cursor: SequenceConstants2.minLocalSequence,
205
209
  order: "desc",
206
210
  payload_schemas: [
207
211
  ModuleStateSchema2
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Schema.ts","../../src/Config.ts","../../src/Diviner.ts","../../src/DivinerMixin.ts"],"sourcesContent":["export const StatefulDivinerSchema = 'network.xyo.diviner.stateful' as const\nexport type StatefulDivinerSchema = typeof StatefulDivinerSchema\n","import type { DivinerConfig } from '@xyo-network/diviner-model'\nimport type { ModuleIdentifier } from '@xyo-network/module-model'\n\nimport { StatefulDivinerSchema } from './Schema.ts'\n\n/**\n * The schema for a Stateful Diviner config\n */\nexport const StatefulDivinerConfigSchema = `${StatefulDivinerSchema}.config` as const\n/**\n * The schema for a Stateful Diviner config\n */\nexport type StatefulDivinerConfigSchema = typeof StatefulDivinerConfigSchema\n\n/**\n * The config for a Stateful Diviner\n */\nexport type StatefulDivinerConfig = DivinerConfig<{\n schema: StatefulDivinerConfigSchema\n stateStore: {\n archivist: ModuleIdentifier\n boundWitnessDiviner: ModuleIdentifier\n payloadDiviner: ModuleIdentifier\n }\n}>\n","import { assertEx } from '@xylabs/assert'\nimport type { Hash } from '@xylabs/hex'\nimport { ArchivistWrapper } from '@xyo-network/archivist-wrapper'\nimport { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'\nimport { isBoundWitness } from '@xyo-network/boundwitness-model'\nimport { AbstractDiviner } from '@xyo-network/diviner-abstract'\nimport type { BoundWitnessDivinerQueryPayload } from '@xyo-network/diviner-boundwitness-model'\nimport { BoundWitnessDivinerQuerySchema } from '@xyo-network/diviner-boundwitness-model'\nimport type { DivinerInstance, DivinerModuleEventData } from '@xyo-network/diviner-model'\nimport { DivinerWrapper } from '@xyo-network/diviner-wrapper'\nimport type { ModuleState, StateDictionary } from '@xyo-network/module-model'\nimport { isModuleState, ModuleStateSchema } from '@xyo-network/module-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport type {\n Payload, Schema, WithMeta,\n} from '@xyo-network/payload-model'\n\nimport { StatefulDivinerConfigSchema } from './Config.ts'\nimport type { StatefulDivinerParams } from './Params.ts'\n\nconst moduleName = 'StatefulDiviner'\n\n/**\n * A Diviner that maintains state\n */\nexport abstract class StatefulDiviner<\n TParams extends StatefulDivinerParams = StatefulDivinerParams,\n TIn extends Payload = Payload,\n TOut extends Payload = Payload,\n TEventData extends DivinerModuleEventData<DivinerInstance<TParams, TIn, TOut>, TIn, TOut> = DivinerModuleEventData<\n DivinerInstance<TParams, TIn, TOut>,\n TIn,\n TOut\n >,\n TState extends StateDictionary = StateDictionary,\n> extends AbstractDiviner<TParams, TIn, TOut, TEventData> {\n static override readonly configSchemas: Schema[] = [...super.configSchemas, StatefulDivinerConfigSchema]\n static override readonly defaultConfigSchema: Schema = StatefulDivinerConfigSchema\n\n /**\n * The last state\n */\n protected _lastState?: WithMeta<ModuleState<TState>>\n\n /**\n * Commit the internal state of the Diviner process. This is similar\n * to a transaction completion in a database and should only be called\n * when results have been successfully persisted to the appropriate\n * external stores.\n * @param nextState The state to commit\n */\n protected async commitState(nextState: WithMeta<ModuleState<TState>>) {\n // Don't commit state if no state has changed\n if (nextState.state.offset === this._lastState?.state.offset) return\n this._lastState = nextState\n const archivist = await this.getArchivistForStateStore()\n const [bw] = await new BoundWitnessBuilder().payload(nextState).signer(this.account).build()\n await archivist.insert([bw, nextState])\n }\n\n /**\n * Retrieves the archivist for the specified store\n * @param store The store to retrieve the archivist for\n * @returns The archivist for the specified store\n */\n protected async getArchivistForStateStore() {\n const name = assertEx(this.config?.stateStore.archivist, () => `${moduleName}: Config for stateStore.archivist not specified`)\n const mod = assertEx(await this.resolve(name), () => `${moduleName}: Failed to resolve stateStore.archivist`)\n return ArchivistWrapper.wrap(mod, this.account)\n }\n\n /**\n * Retrieves the BoundWitness Diviner for the specified store\n * @param store The store to retrieve the BoundWitness Diviner for\n * @returns The BoundWitness Diviner for the specified store\n */\n protected async getBoundWitnessDivinerForStateStore() {\n const name = assertEx(this.config?.stateStore.boundWitnessDiviner, () => `${moduleName}: Config for stateStore.boundWitnessDiviner not specified`)\n const mod = assertEx(await this.resolve(name), () => `${moduleName}: Failed to resolve stateStore.boundWitnessDiviner`)\n return DivinerWrapper.wrap(mod, this.account)\n }\n\n /**\n * Retrieves the Payload Diviner for the specified store\n * @param store The store to retrieve the Payload Diviner for\n * @returns The Payload Diviner for the specified store\n */\n protected async getPayloadDivinerForStateStore() {\n const name = assertEx(this.config?.stateStore?.payloadDiviner, () => `${moduleName}: Config for stateStore.payloadDiviner not specified`)\n const mod = assertEx(await this.resolve(name), () => `${moduleName}: Failed to resolve stateStore.payloadDiviner`)\n return DivinerWrapper.wrap(mod, this.account)\n }\n\n /**\n * Retrieves the last state of the Diviner process. Used to recover state after\n * preemptions, reboots, etc.\n */\n protected async retrieveState(): Promise<WithMeta<ModuleState<TState>> | undefined> {\n if (this._lastState) return this._lastState\n let hash: Hash = ''\n const diviner = await this.getBoundWitnessDivinerForStateStore()\n const query = await new PayloadBuilder<BoundWitnessDivinerQueryPayload>({ schema: BoundWitnessDivinerQuerySchema })\n .fields({\n address: this.account.address,\n limit: 1,\n offset: 0,\n order: 'desc',\n payload_schemas: [ModuleStateSchema],\n })\n .build()\n const boundWitnesses = await diviner.divine([query])\n if (boundWitnesses.length > 0) {\n const boundWitness = boundWitnesses[0]\n if (isBoundWitness(boundWitness)) {\n // Find the index for this address in the BoundWitness that is a ModuleState\n hash = boundWitness.addresses\n .map((address, index) => ({ address, index }))\n .filter(({ address }) => address === this.account.address)\n // eslint-disable-next-line unicorn/no-array-reduce\n .reduce(\n (prev, curr) => (boundWitness.payload_schemas?.[curr?.index] === ModuleStateSchema ? boundWitness.payload_hashes[curr?.index] : prev),\n '' as Hash,\n )\n }\n }\n\n // If we able to located the last state\n if (hash) {\n // Get last state\n const archivist = await this.getArchivistForStateStore()\n const payload = (await archivist.get([hash])).find(isModuleState<TState>)\n if (payload) {\n return payload as WithMeta<ModuleState<TState>>\n }\n }\n return undefined\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport type { Hash } from '@xylabs/hex'\nimport { asArchivistInstance } from '@xyo-network/archivist-model'\nimport { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'\nimport { isBoundWitness } from '@xyo-network/boundwitness-model'\nimport type { BoundWitnessDivinerQueryPayload } from '@xyo-network/diviner-boundwitness-model'\nimport { BoundWitnessDivinerQuerySchema } from '@xyo-network/diviner-boundwitness-model'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport type {\n AnyConfigSchema,\n ModuleInstance,\n ModuleParams,\n ModuleState,\n StateDictionary,\n} from '@xyo-network/module-model'\nimport {\n isModuleState,\n ModuleStateSchema,\n} from '@xyo-network/module-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport type { WithMeta } from '@xyo-network/payload-model'\n\nimport type { StatefulDivinerConfig } from './Config.ts'\n\nexport type StatefulModuleParams = ModuleParams<AnyConfigSchema<StatefulDivinerConfig>>\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyModule<TParams extends StatefulModuleParams = StatefulModuleParams> = new (...args: any[]) => ModuleInstance<TParams>\n\nconst moduleName = 'StatefulModuleMixin'\n\n/**\n * @ignore Inherit from StatefulDiviner instead\n * @param ModuleBase\n * @returns\n */\nexport const StatefulModuleMixin = <\n TParams extends StatefulModuleParams = StatefulModuleParams,\n TModule extends AnyModule<TParams> = AnyModule<TParams>,\n TState extends StateDictionary = StateDictionary,\n>(\n ModuleBase: TModule,\n) => {\n abstract class StatefulModuleBase extends ModuleBase {\n _lastState?: WithMeta<ModuleState<TState>>\n\n /**\n * Commit the internal state of the Diviner process. This is similar\n * to a transaction completion in a database and should only be called\n * when results have been successfully persisted to the appropriate\n * external stores.\n * @param nextState The state to commit\n */\n async commitState(nextState: WithMeta<ModuleState<TState>>) {\n // Don't commit state if no state has changed\n if (nextState.state.offset === this._lastState?.state.offset) return\n this._lastState = nextState\n const archivist = await this.getArchivistForStore()\n // const [bw] = await new BoundWitnessBuilder().payload(nextState).signer(this.account).build()\n const [bw] = await (await new BoundWitnessBuilder().payload(nextState)).build()\n await archivist.insert([bw, nextState])\n }\n\n /**\n * Retrieves the archivist for the specified store\n * @param store The store to retrieve the archivist for\n * @returns The archivist for the specified store\n */\n async getArchivistForStore() {\n const name = assertEx(this.config?.stateStore?.archivist, () => `${moduleName}: Config for stateStore.archivist not specified`)\n const mod = assertEx(await this.resolve(name), () => `${moduleName}: Failed to resolve stateStore.archivist`)\n // return ArchivistWrapper.wrap(mod, this.account)\n const instance = asArchivistInstance(mod)\n return assertEx(instance, () => `${moduleName}: Failed to wrap archivist instance`)\n }\n\n /**\n * Retrieves the BoundWitness Diviner for the specified store\n * @param store The store to retrieve the BoundWitness Diviner for\n * @returns The BoundWitness Diviner for the specified store\n */\n async getBoundWitnessDivinerForStore() {\n const name = assertEx(\n this.config?.stateStore?.boundWitnessDiviner,\n () => `${moduleName}: Config for stateStore.boundWitnessDiviner not specified`,\n )\n const mod = assertEx(await this.resolve(name), () => `${moduleName}: Failed to resolve stateStore.boundWitnessDiviner`)\n // return DivinerWrapper.wrap(mod, this.account)\n const instance = asDivinerInstance(mod)\n return assertEx(instance, () => `${moduleName}: Failed to wrap diviner instance`)\n }\n\n /**\n * Retrieves the Payload Diviner for the specified store\n * @param store The store to retrieve the Payload Diviner for\n * @returns The Payload Diviner for the specified store\n */\n async getPayloadDivinerForStateStore() {\n const name = assertEx(this.config?.stateStore?.payloadDiviner, () => `${moduleName}: Config for stateStore.payloadDiviner not specified`)\n const mod = assertEx(await this.resolve(name), () => `${moduleName}: Failed to resolve stateStore.payloadDiviner`)\n // return DivinerWrapper.wrap(mod, this.account)\n const instance = asDivinerInstance(mod)\n return assertEx(instance, () => `${moduleName}: Failed to wrap diviner instance`)\n }\n\n /**\n * Retrieves the last state of the Diviner process. Used to recover state after\n * preemptions, reboots, etc.\n */\n async retrieveState(): Promise<WithMeta<ModuleState<TState>> | undefined> {\n if (this._lastState) return this._lastState\n let hash: Hash = ''\n const diviner = await this.getBoundWitnessDivinerForStore()\n const query = await new PayloadBuilder<BoundWitnessDivinerQueryPayload>({ schema: BoundWitnessDivinerQuerySchema })\n .fields({\n // address: this.account.address,\n limit: 1,\n offset: 0,\n order: 'desc',\n payload_schemas: [ModuleStateSchema],\n })\n .build()\n const boundWitnesses = await diviner.divine([query])\n if (boundWitnesses.length > 0) {\n const boundWitness = boundWitnesses[0]\n if (isBoundWitness(boundWitness)) {\n // Find the index for this address in the BoundWitness that is a ModuleState\n hash = boundWitness.addresses\n .map((address, index) => ({ address, index }))\n // .filter(({ address }) => address === this.account.address)\n // eslint-disable-next-line unicorn/no-array-reduce\n .reduce(\n (prev, curr) => (boundWitness.payload_schemas?.[curr?.index] === ModuleStateSchema ? boundWitness.payload_hashes[curr?.index] : prev),\n '' as Hash,\n )\n }\n }\n\n // If we able to located the last state\n if (hash) {\n // Get last state\n const archivist = await this.getArchivistForStore()\n const payload = (await archivist.get([hash])).find(isModuleState<TState>)\n if (payload) {\n return payload as WithMeta<ModuleState<TState>>\n }\n }\n return undefined\n }\n }\n return StatefulModuleBase\n}\n"],"mappings":"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","names":["StatefulDivinerSchema","StatefulDivinerConfigSchema","StatefulDivinerSchema","assertEx","ArchivistWrapper","BoundWitnessBuilder","isBoundWitness","AbstractDiviner","BoundWitnessDivinerQuerySchema","DivinerWrapper","isModuleState","ModuleStateSchema","PayloadBuilder","moduleName","StatefulDiviner","AbstractDiviner","configSchemas","StatefulDivinerConfigSchema","defaultConfigSchema","_lastState","commitState","nextState","state","offset","archivist","getArchivistForStateStore","bw","BoundWitnessBuilder","payload","signer","account","build","insert","name","assertEx","config","stateStore","mod","resolve","ArchivistWrapper","wrap","getBoundWitnessDivinerForStateStore","boundWitnessDiviner","DivinerWrapper","getPayloadDivinerForStateStore","payloadDiviner","retrieveState","hash","diviner","query","PayloadBuilder","schema","BoundWitnessDivinerQuerySchema","fields","address","limit","order","payload_schemas","ModuleStateSchema","boundWitnesses","divine","length","boundWitness","isBoundWitness","addresses","map","index","filter","reduce","prev","curr","payload_hashes","get","find","isModuleState","undefined","assertEx","asArchivistInstance","BoundWitnessBuilder","isBoundWitness","BoundWitnessDivinerQuerySchema","asDivinerInstance","isModuleState","ModuleStateSchema","PayloadBuilder","moduleName","StatefulModuleMixin","ModuleBase","StatefulModuleBase","_lastState","commitState","nextState","state","offset","archivist","getArchivistForStore","bw","BoundWitnessBuilder","payload","build","insert","name","assertEx","config","stateStore","mod","resolve","instance","asArchivistInstance","getBoundWitnessDivinerForStore","boundWitnessDiviner","asDivinerInstance","getPayloadDivinerForStateStore","payloadDiviner","retrieveState","hash","diviner","query","PayloadBuilder","schema","BoundWitnessDivinerQuerySchema","fields","limit","order","payload_schemas","ModuleStateSchema","boundWitnesses","divine","length","boundWitness","isBoundWitness","addresses","map","address","index","reduce","prev","curr","payload_hashes","get","find","isModuleState","undefined"]}
1
+ {"version":3,"sources":["../../src/Schema.ts","../../src/Config.ts","../../src/Diviner.ts","../../src/DivinerMixin.ts"],"sourcesContent":["export const StatefulDivinerSchema = 'network.xyo.diviner.stateful' as const\nexport type StatefulDivinerSchema = typeof StatefulDivinerSchema\n","import type { DivinerConfig } from '@xyo-network/diviner-model'\nimport type { ModuleIdentifier } from '@xyo-network/module-model'\n\nimport { StatefulDivinerSchema } from './Schema.ts'\n\n/**\n * The schema for a Stateful Diviner config\n */\nexport const StatefulDivinerConfigSchema = `${StatefulDivinerSchema}.config` as const\n/**\n * The schema for a Stateful Diviner config\n */\nexport type StatefulDivinerConfigSchema = typeof StatefulDivinerConfigSchema\n\n/**\n * The config for a Stateful Diviner\n */\nexport type StatefulDivinerConfig = DivinerConfig<{\n schema: StatefulDivinerConfigSchema\n stateStore: {\n archivist: ModuleIdentifier\n boundWitnessDiviner: ModuleIdentifier\n payloadDiviner: ModuleIdentifier\n }\n}>\n","import { assertEx } from '@xylabs/assert'\nimport type { Hash } from '@xylabs/hex'\nimport { toJson } from '@xylabs/object'\nimport { ArchivistWrapper } from '@xyo-network/archivist-wrapper'\nimport { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'\nimport { isBoundWitness } from '@xyo-network/boundwitness-model'\nimport { AbstractDiviner } from '@xyo-network/diviner-abstract'\nimport type { BoundWitnessDivinerQueryPayload } from '@xyo-network/diviner-boundwitness-model'\nimport { BoundWitnessDivinerQuerySchema } from '@xyo-network/diviner-boundwitness-model'\nimport type { DivinerInstance, DivinerModuleEventData } from '@xyo-network/diviner-model'\nimport { DivinerWrapper } from '@xyo-network/diviner-wrapper'\nimport type { ModuleState, StateDictionary } from '@xyo-network/module-model'\nimport { isModuleState, ModuleStateSchema } from '@xyo-network/module-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport {\n type Payload, type Schema, SequenceConstants,\n type WithStorageMeta,\n} from '@xyo-network/payload-model'\n\nimport { StatefulDivinerConfigSchema } from './Config.ts'\nimport type { StatefulDivinerParams } from './Params.ts'\n\nconst moduleName = 'StatefulDiviner'\n\n/**\n * A Diviner that maintains state\n */\nexport abstract class StatefulDiviner<\n TParams extends StatefulDivinerParams = StatefulDivinerParams,\n TIn extends Payload = Payload,\n TOut extends Payload = Payload,\n TEventData extends DivinerModuleEventData<DivinerInstance<TParams, TIn, TOut>, TIn, TOut> = DivinerModuleEventData<\n DivinerInstance<TParams, TIn, TOut>,\n TIn,\n TOut\n >,\n TState extends StateDictionary = StateDictionary,\n> extends AbstractDiviner<TParams, TIn, TOut, TEventData> {\n static override readonly configSchemas: Schema[] = [...super.configSchemas, StatefulDivinerConfigSchema]\n static override readonly defaultConfigSchema: Schema = StatefulDivinerConfigSchema\n\n /**\n * The last state\n */\n protected _lastState?: ModuleState<TState>\n\n /**\n * Commit the internal state of the Diviner process. This is similar\n * to a transaction completion in a database and should only be called\n * when results have been successfully persisted to the appropriate\n * external stores.\n * @param nextState The state to commit\n */\n protected async commitState(nextState: ModuleState<TState>) {\n // Don't commit state if no state has changed\n if (toJson(nextState.state) === toJson(this._lastState?.state)) return\n this._lastState = nextState\n const archivist = await this.getArchivistForStateStore()\n const [bw] = await new BoundWitnessBuilder().payload(nextState).signer(this.account).build()\n await archivist.insert([bw, nextState])\n }\n\n /**\n * Retrieves the archivist for the specified store\n * @param store The store to retrieve the archivist for\n * @returns The archivist for the specified store\n */\n protected async getArchivistForStateStore() {\n const name = assertEx(this.config?.stateStore.archivist, () => `${moduleName}: Config for stateStore.archivist not specified`)\n const mod = assertEx(await this.resolve(name), () => `${moduleName}: Failed to resolve stateStore.archivist`)\n return ArchivistWrapper.wrap(mod, this.account)\n }\n\n /**\n * Retrieves the BoundWitness Diviner for the specified store\n * @param store The store to retrieve the BoundWitness Diviner for\n * @returns The BoundWitness Diviner for the specified store\n */\n protected async getBoundWitnessDivinerForStateStore() {\n const name = assertEx(this.config?.stateStore.boundWitnessDiviner, () => `${moduleName}: Config for stateStore.boundWitnessDiviner not specified`)\n const mod = assertEx(await this.resolve(name), () => `${moduleName}: Failed to resolve stateStore.boundWitnessDiviner`)\n return DivinerWrapper.wrap(mod, this.account)\n }\n\n /**\n * Retrieves the Payload Diviner for the specified store\n * @param store The store to retrieve the Payload Diviner for\n * @returns The Payload Diviner for the specified store\n */\n protected async getPayloadDivinerForStateStore() {\n const name = assertEx(this.config?.stateStore?.payloadDiviner, () => `${moduleName}: Config for stateStore.payloadDiviner not specified`)\n const mod = assertEx(await this.resolve(name), () => `${moduleName}: Failed to resolve stateStore.payloadDiviner`)\n return DivinerWrapper.wrap(mod, this.account)\n }\n\n /**\n * Retrieves the last state of the Diviner process. Used to recover state after\n * preemptions, reboots, etc.\n */\n protected async retrieveState(): Promise<ModuleState<TState> | undefined> {\n if (this._lastState) return this._lastState\n let hash: Hash = ''\n const diviner = await this.getBoundWitnessDivinerForStateStore()\n const query = await new PayloadBuilder<BoundWitnessDivinerQueryPayload>({ schema: BoundWitnessDivinerQuerySchema })\n .fields({\n address: this.account.address,\n limit: 1,\n cursor: SequenceConstants.minLocalSequence,\n order: 'desc',\n payload_schemas: [ModuleStateSchema],\n })\n .build()\n const boundWitnesses = await diviner.divine([query])\n if (boundWitnesses.length > 0) {\n const boundWitness = boundWitnesses[0]\n if (isBoundWitness(boundWitness)) {\n // Find the index for this address in the BoundWitness that is a ModuleState\n hash = boundWitness.addresses\n .map((address, index) => ({ address, index }))\n .filter(({ address }) => address === this.account.address)\n // eslint-disable-next-line unicorn/no-array-reduce\n .reduce(\n (prev, curr) => (boundWitness.payload_schemas?.[curr?.index] === ModuleStateSchema ? boundWitness.payload_hashes[curr?.index] : prev),\n '' as Hash,\n )\n }\n }\n\n // If we able to located the last state\n if (hash) {\n // Get last state\n const archivist = await this.getArchivistForStateStore()\n const payload = (await archivist.get([hash])).find(isModuleState<TState>)\n if (payload) {\n return payload as WithStorageMeta<ModuleState<TState>>\n }\n }\n return undefined\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport type { Hash } from '@xylabs/hex'\nimport { toJson } from '@xylabs/object'\nimport { asArchivistInstance } from '@xyo-network/archivist-model'\nimport { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'\nimport { isBoundWitness } from '@xyo-network/boundwitness-model'\nimport type { BoundWitnessDivinerQueryPayload } from '@xyo-network/diviner-boundwitness-model'\nimport { BoundWitnessDivinerQuerySchema } from '@xyo-network/diviner-boundwitness-model'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport type {\n AnyConfigSchema,\n ModuleInstance,\n ModuleParams,\n ModuleState,\n StateDictionary,\n} from '@xyo-network/module-model'\nimport {\n isModuleState,\n ModuleStateSchema,\n} from '@xyo-network/module-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { SequenceConstants, type WithStorageMeta } from '@xyo-network/payload-model'\n\nimport type { StatefulDivinerConfig } from './Config.ts'\n\nexport type StatefulModuleParams = ModuleParams<AnyConfigSchema<StatefulDivinerConfig>>\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyModule<TParams extends StatefulModuleParams = StatefulModuleParams> = new (...args: any[]) => ModuleInstance<TParams>\n\nconst moduleName = 'StatefulModuleMixin'\n\n/**\n * @ignore Inherit from StatefulDiviner instead\n * @param ModuleBase\n * @returns\n */\nexport const StatefulModuleMixin = <\n TParams extends StatefulModuleParams = StatefulModuleParams,\n TModule extends AnyModule<TParams> = AnyModule<TParams>,\n TState extends StateDictionary = StateDictionary,\n>(\n ModuleBase: TModule,\n) => {\n abstract class StatefulModuleBase extends ModuleBase {\n _lastState?: ModuleState<TState>\n\n /**\n * Commit the internal state of the Diviner process. This is similar\n * to a transaction completion in a database and should only be called\n * when results have been successfully persisted to the appropriate\n * external stores.\n * @param nextState The state to commit\n */\n async commitState(nextState: ModuleState<TState>) {\n // Don't commit state if no state has changed\n if (toJson(nextState.state) === toJson(this._lastState?.state)) return\n this._lastState = nextState\n const archivist = await this.getArchivistForStore()\n // const [bw] = await new BoundWitnessBuilder().payload(nextState).signer(this.account).build()\n const [bw] = await (await new BoundWitnessBuilder().payload(nextState)).build()\n await archivist.insert([bw, nextState])\n }\n\n /**\n * Retrieves the archivist for the specified store\n * @param store The store to retrieve the archivist for\n * @returns The archivist for the specified store\n */\n async getArchivistForStore() {\n const name = assertEx(this.config?.stateStore?.archivist, () => `${moduleName}: Config for stateStore.archivist not specified`)\n const mod = assertEx(await this.resolve(name), () => `${moduleName}: Failed to resolve stateStore.archivist`)\n // return ArchivistWrapper.wrap(mod, this.account)\n const instance = asArchivistInstance(mod)\n return assertEx(instance, () => `${moduleName}: Failed to wrap archivist instance`)\n }\n\n /**\n * Retrieves the BoundWitness Diviner for the specified store\n * @param store The store to retrieve the BoundWitness Diviner for\n * @returns The BoundWitness Diviner for the specified store\n */\n async getBoundWitnessDivinerForStore() {\n const name = assertEx(\n this.config?.stateStore?.boundWitnessDiviner,\n () => `${moduleName}: Config for stateStore.boundWitnessDiviner not specified`,\n )\n const mod = assertEx(await this.resolve(name), () => `${moduleName}: Failed to resolve stateStore.boundWitnessDiviner`)\n // return DivinerWrapper.wrap(mod, this.account)\n const instance = asDivinerInstance(mod)\n return assertEx(instance, () => `${moduleName}: Failed to wrap diviner instance`)\n }\n\n /**\n * Retrieves the Payload Diviner for the specified store\n * @param store The store to retrieve the Payload Diviner for\n * @returns The Payload Diviner for the specified store\n */\n async getPayloadDivinerForStateStore() {\n const name = assertEx(this.config?.stateStore?.payloadDiviner, () => `${moduleName}: Config for stateStore.payloadDiviner not specified`)\n const mod = assertEx(await this.resolve(name), () => `${moduleName}: Failed to resolve stateStore.payloadDiviner`)\n // return DivinerWrapper.wrap(mod, this.account)\n const instance = asDivinerInstance(mod)\n return assertEx(instance, () => `${moduleName}: Failed to wrap diviner instance`)\n }\n\n /**\n * Retrieves the last state of the Diviner process. Used to recover state after\n * preemptions, reboots, etc.\n */\n async retrieveState(): Promise<ModuleState<TState> | undefined> {\n if (this._lastState) return this._lastState\n let hash: Hash = ''\n const diviner = await this.getBoundWitnessDivinerForStore()\n const query = await new PayloadBuilder<BoundWitnessDivinerQueryPayload>({ schema: BoundWitnessDivinerQuerySchema })\n .fields({\n // address: this.account.address,\n limit: 1,\n cursor: SequenceConstants.minLocalSequence,\n order: 'desc',\n payload_schemas: [ModuleStateSchema],\n })\n .build()\n const boundWitnesses = await diviner.divine([query])\n if (boundWitnesses.length > 0) {\n const boundWitness = boundWitnesses[0]\n if (isBoundWitness(boundWitness)) {\n // Find the index for this address in the BoundWitness that is a ModuleState\n hash = boundWitness.addresses\n .map((address, index) => ({ address, index }))\n // .filter(({ address }) => address === this.account.address)\n // eslint-disable-next-line unicorn/no-array-reduce\n .reduce(\n (prev, curr) => (boundWitness.payload_schemas?.[curr?.index] === ModuleStateSchema ? boundWitness.payload_hashes[curr?.index] : prev),\n '' as Hash,\n )\n }\n }\n\n // If we able to located the last state\n if (hash) {\n // Get last state\n const archivist = await this.getArchivistForStore()\n const payload = (await archivist.get([hash])).find(isModuleState<TState>)\n if (payload) {\n return payload as WithStorageMeta<ModuleState<TState>>\n }\n }\n return undefined\n }\n }\n return StatefulModuleBase\n}\n"],"mappings":";;;;AAAO,IAAMA,wBAAwB;;;ACQ9B,IAAMC,8BAA8B,GAAGC,qBAAAA;;;ACR9C,SAASC,gBAAgB;AAEzB,SAASC,cAAc;AACvB,SAASC,wBAAwB;AACjC,SAASC,2BAA2B;AACpC,SAASC,sBAAsB;AAC/B,SAASC,uBAAuB;AAEhC,SAASC,sCAAsC;AAE/C,SAASC,sBAAsB;AAE/B,SAASC,eAAeC,yBAAyB;AACjD,SAASC,sBAAsB;AAC/B,SAC6BC,yBAEtB;AAKP,IAAMC,aAAa;AAKZ,IAAeC,kBAAf,cAUGC,gBAAAA;EArCV,OAqCUA;;;EACR,OAAyBC,gBAA0B;OAAI,MAAMA;IAAeC;;EAC5E,OAAyBC,sBAA8BD;;;;EAK7CE;;;;;;;;EASV,MAAgBC,YAAYC,WAAgC;AAE1D,QAAIC,OAAOD,UAAUE,KAAK,MAAMD,OAAO,KAAKH,YAAYI,KAAAA,EAAQ;AAChE,SAAKJ,aAAaE;AAClB,UAAMG,YAAY,MAAM,KAAKC,0BAAyB;AACtD,UAAM,CAACC,EAAAA,IAAM,MAAM,IAAIC,oBAAAA,EAAsBC,QAAQP,SAAAA,EAAWQ,OAAO,KAAKC,OAAO,EAAEC,MAAK;AAC1F,UAAMP,UAAUQ,OAAO;MAACN;MAAIL;KAAU;EACxC;;;;;;EAOA,MAAgBI,4BAA4B;AAC1C,UAAMQ,OAAOC,SAAS,KAAKC,QAAQC,WAAWZ,WAAW,MAAM,GAAGX,UAAAA,iDAA2D;AAC7H,UAAMwB,MAAMH,SAAS,MAAM,KAAKI,QAAQL,IAAAA,GAAO,MAAM,GAAGpB,UAAAA,0CAAoD;AAC5G,WAAO0B,iBAAiBC,KAAKH,KAAK,KAAKP,OAAO;EAChD;;;;;;EAOA,MAAgBW,sCAAsC;AACpD,UAAMR,OAAOC,SAAS,KAAKC,QAAQC,WAAWM,qBAAqB,MAAM,GAAG7B,UAAAA,2DAAqE;AACjJ,UAAMwB,MAAMH,SAAS,MAAM,KAAKI,QAAQL,IAAAA,GAAO,MAAM,GAAGpB,UAAAA,oDAA8D;AACtH,WAAO8B,eAAeH,KAAKH,KAAK,KAAKP,OAAO;EAC9C;;;;;;EAOA,MAAgBc,iCAAiC;AAC/C,UAAMX,OAAOC,SAAS,KAAKC,QAAQC,YAAYS,gBAAgB,MAAM,GAAGhC,UAAAA,sDAAgE;AACxI,UAAMwB,MAAMH,SAAS,MAAM,KAAKI,QAAQL,IAAAA,GAAO,MAAM,GAAGpB,UAAAA,+CAAyD;AACjH,WAAO8B,eAAeH,KAAKH,KAAK,KAAKP,OAAO;EAC9C;;;;;EAMA,MAAgBgB,gBAA0D;AACxE,QAAI,KAAK3B,WAAY,QAAO,KAAKA;AACjC,QAAI4B,OAAa;AACjB,UAAMC,UAAU,MAAM,KAAKP,oCAAmC;AAC9D,UAAMQ,QAAQ,MAAM,IAAIC,eAAgD;MAAEC,QAAQC;IAA+B,CAAA,EAC9GC,OAAO;MACNC,SAAS,KAAKxB,QAAQwB;MACtBC,OAAO;MACPC,QAAQC,kBAAkBC;MAC1BC,OAAO;MACPC,iBAAiB;QAACC;;IACpB,CAAA,EACC9B,MAAK;AACR,UAAM+B,iBAAiB,MAAMd,QAAQe,OAAO;MAACd;KAAM;AACnD,QAAIa,eAAeE,SAAS,GAAG;AAC7B,YAAMC,eAAeH,eAAe,CAAA;AACpC,UAAII,eAAeD,YAAAA,GAAe;AAEhClB,eAAOkB,aAAaE,UACjBC,IAAI,CAACd,SAASe,WAAW;UAAEf;UAASe;QAAM,EAAA,EAC1CC,OAAO,CAAC,EAAEhB,QAAO,MAAOA,YAAY,KAAKxB,QAAQwB,OAAO,EAExDiB,OACC,CAACC,MAAMC,SAAUR,aAAaL,kBAAkBa,MAAMJ,KAAAA,MAAWR,oBAAoBI,aAAaS,eAAeD,MAAMJ,KAAAA,IAASG,MAChI,EAAA;MAEN;IACF;AAGA,QAAIzB,MAAM;AAER,YAAMvB,YAAY,MAAM,KAAKC,0BAAyB;AACtD,YAAMG,WAAW,MAAMJ,UAAUmD,IAAI;QAAC5B;OAAK,GAAG6B,KAAKC,aAAAA;AACnD,UAAIjD,SAAS;AACX,eAAOA;MACT;IACF;AACA,WAAOkD;EACT;AACF;;;AC3IA,SAASC,YAAAA,iBAAgB;AAEzB,SAASC,UAAAA,eAAc;AACvB,SAASC,2BAA2B;AACpC,SAASC,uBAAAA,4BAA2B;AACpC,SAASC,kBAAAA,uBAAsB;AAE/B,SAASC,kCAAAA,uCAAsC;AAC/C,SAASC,yBAAyB;AAQlC,SACEC,iBAAAA,gBACAC,qBAAAA,0BACK;AACP,SAASC,kBAAAA,uBAAsB;AAC/B,SAASC,qBAAAA,0BAA+C;AASxD,IAAMC,cAAa;AAOZ,IAAMC,sBAAsB,wBAKjCC,eAAAA;AAEA,MAAeC,qBAAf,MAAeA,2BAA2BD,WAAAA;IA5C5C,OA4C4CA;;;IACxCE;;;;;;;;IASA,MAAMC,YAAYC,WAAgC;AAEhD,UAAIC,QAAOD,UAAUE,KAAK,MAAMD,QAAO,KAAKH,YAAYI,KAAAA,EAAQ;AAChE,WAAKJ,aAAaE;AAClB,YAAMG,YAAY,MAAM,KAAKC,qBAAoB;AAEjD,YAAM,CAACC,EAAAA,IAAM,OAAO,MAAM,IAAIC,qBAAAA,EAAsBC,QAAQP,SAAAA,GAAYQ,MAAK;AAC7E,YAAML,UAAUM,OAAO;QAACJ;QAAIL;OAAU;IACxC;;;;;;IAOA,MAAMI,uBAAuB;AAC3B,YAAMM,OAAOC,UAAS,KAAKC,QAAQC,YAAYV,WAAW,MAAM,GAAGT,WAAAA,iDAA2D;AAC9H,YAAMoB,MAAMH,UAAS,MAAM,KAAKI,QAAQL,IAAAA,GAAO,MAAM,GAAGhB,WAAAA,0CAAoD;AAE5G,YAAMsB,WAAWC,oBAAoBH,GAAAA;AACrC,aAAOH,UAASK,UAAU,MAAM,GAAGtB,WAAAA,qCAA+C;IACpF;;;;;;IAOA,MAAMwB,iCAAiC;AACrC,YAAMR,OAAOC,UACX,KAAKC,QAAQC,YAAYM,qBACzB,MAAM,GAAGzB,WAAAA,2DAAqE;AAEhF,YAAMoB,MAAMH,UAAS,MAAM,KAAKI,QAAQL,IAAAA,GAAO,MAAM,GAAGhB,WAAAA,oDAA8D;AAEtH,YAAMsB,WAAWI,kBAAkBN,GAAAA;AACnC,aAAOH,UAASK,UAAU,MAAM,GAAGtB,WAAAA,mCAA6C;IAClF;;;;;;IAOA,MAAM2B,iCAAiC;AACrC,YAAMX,OAAOC,UAAS,KAAKC,QAAQC,YAAYS,gBAAgB,MAAM,GAAG5B,WAAAA,sDAAgE;AACxI,YAAMoB,MAAMH,UAAS,MAAM,KAAKI,QAAQL,IAAAA,GAAO,MAAM,GAAGhB,WAAAA,+CAAyD;AAEjH,YAAMsB,WAAWI,kBAAkBN,GAAAA;AACnC,aAAOH,UAASK,UAAU,MAAM,GAAGtB,WAAAA,mCAA6C;IAClF;;;;;IAMA,MAAM6B,gBAA0D;AAC9D,UAAI,KAAKzB,WAAY,QAAO,KAAKA;AACjC,UAAI0B,OAAa;AACjB,YAAMC,UAAU,MAAM,KAAKP,+BAA8B;AACzD,YAAMQ,QAAQ,MAAM,IAAIC,gBAAgD;QAAEC,QAAQC;MAA+B,CAAA,EAC9GC,OAAO;;QAENC,OAAO;QACPC,QAAQC,mBAAkBC;QAC1BC,OAAO;QACPC,iBAAiB;UAACC;;MACpB,CAAA,EACC7B,MAAK;AACR,YAAM8B,iBAAiB,MAAMb,QAAQc,OAAO;QAACb;OAAM;AACnD,UAAIY,eAAeE,SAAS,GAAG;AAC7B,cAAMC,eAAeH,eAAe,CAAA;AACpC,YAAII,gBAAeD,YAAAA,GAAe;AAEhCjB,iBAAOiB,aAAaE,UACjBC,IAAI,CAACC,SAASC,WAAW;YAAED;YAASC;UAAM,EAAA,EAG1CC,OACC,CAACC,MAAMC,SAAUR,aAAaL,kBAAkBa,MAAMH,KAAAA,MAAWT,qBAAoBI,aAAaS,eAAeD,MAAMH,KAAAA,IAASE,MAChI,EAAA;QAEN;MACF;AAGA,UAAIxB,MAAM;AAER,cAAMrB,YAAY,MAAM,KAAKC,qBAAoB;AACjD,cAAMG,WAAW,MAAMJ,UAAUgD,IAAI;UAAC3B;SAAK,GAAG4B,KAAKC,cAAAA;AACnD,YAAI9C,SAAS;AACX,iBAAOA;QACT;MACF;AACA,aAAO+C;IACT;EACF;AACA,SAAOzD;AACT,GAnHmC;","names":["StatefulDivinerSchema","StatefulDivinerConfigSchema","StatefulDivinerSchema","assertEx","toJson","ArchivistWrapper","BoundWitnessBuilder","isBoundWitness","AbstractDiviner","BoundWitnessDivinerQuerySchema","DivinerWrapper","isModuleState","ModuleStateSchema","PayloadBuilder","SequenceConstants","moduleName","StatefulDiviner","AbstractDiviner","configSchemas","StatefulDivinerConfigSchema","defaultConfigSchema","_lastState","commitState","nextState","toJson","state","archivist","getArchivistForStateStore","bw","BoundWitnessBuilder","payload","signer","account","build","insert","name","assertEx","config","stateStore","mod","resolve","ArchivistWrapper","wrap","getBoundWitnessDivinerForStateStore","boundWitnessDiviner","DivinerWrapper","getPayloadDivinerForStateStore","payloadDiviner","retrieveState","hash","diviner","query","PayloadBuilder","schema","BoundWitnessDivinerQuerySchema","fields","address","limit","cursor","SequenceConstants","minLocalSequence","order","payload_schemas","ModuleStateSchema","boundWitnesses","divine","length","boundWitness","isBoundWitness","addresses","map","index","filter","reduce","prev","curr","payload_hashes","get","find","isModuleState","undefined","assertEx","toJson","asArchivistInstance","BoundWitnessBuilder","isBoundWitness","BoundWitnessDivinerQuerySchema","asDivinerInstance","isModuleState","ModuleStateSchema","PayloadBuilder","SequenceConstants","moduleName","StatefulModuleMixin","ModuleBase","StatefulModuleBase","_lastState","commitState","nextState","toJson","state","archivist","getArchivistForStore","bw","BoundWitnessBuilder","payload","build","insert","name","assertEx","config","stateStore","mod","resolve","instance","asArchivistInstance","getBoundWitnessDivinerForStore","boundWitnessDiviner","asDivinerInstance","getPayloadDivinerForStateStore","payloadDiviner","retrieveState","hash","diviner","query","PayloadBuilder","schema","BoundWitnessDivinerQuerySchema","fields","limit","cursor","SequenceConstants","minLocalSequence","order","payload_schemas","ModuleStateSchema","boundWitnesses","divine","length","boundWitness","isBoundWitness","addresses","map","address","index","reduce","prev","curr","payload_hashes","get","find","isModuleState","undefined"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/diviner-stateful",
3
- "version": "3.5.2",
3
+ "version": "3.6.0-rc.10",
4
4
  "description": "Primary SDK for using XYO Protocol 2.0",
5
5
  "homepage": "https://xyo.network",
6
6
  "bugs": {
@@ -29,35 +29,37 @@
29
29
  "module": "dist/neutral/index.mjs",
30
30
  "types": "dist/neutral/index.d.ts",
31
31
  "dependencies": {
32
- "@xylabs/assert": "^4.4.9",
33
- "@xylabs/hex": "^4.4.9",
34
- "@xyo-network/archivist-model": "^3.5.2",
35
- "@xyo-network/archivist-wrapper": "^3.5.2",
36
- "@xyo-network/boundwitness-builder": "^3.5.2",
37
- "@xyo-network/boundwitness-model": "^3.5.2",
38
- "@xyo-network/diviner-abstract": "^3.5.2",
39
- "@xyo-network/diviner-boundwitness-model": "^3.5.2",
40
- "@xyo-network/diviner-model": "^3.5.2",
41
- "@xyo-network/diviner-wrapper": "^3.5.2",
42
- "@xyo-network/module-model": "^3.5.2",
43
- "@xyo-network/payload-builder": "^3.5.2",
44
- "@xyo-network/payload-model": "^3.5.2"
32
+ "@xylabs/assert": "^4.4.21",
33
+ "@xylabs/hex": "^4.4.21",
34
+ "@xylabs/object": "^4.4.21",
35
+ "@xyo-network/archivist-model": "^3.6.0-rc.10",
36
+ "@xyo-network/archivist-wrapper": "^3.6.0-rc.10",
37
+ "@xyo-network/boundwitness-builder": "^3.6.0-rc.10",
38
+ "@xyo-network/boundwitness-model": "^3.6.0-rc.10",
39
+ "@xyo-network/diviner-abstract": "^3.6.0-rc.10",
40
+ "@xyo-network/diviner-boundwitness-model": "^3.6.0-rc.10",
41
+ "@xyo-network/diviner-model": "^3.6.0-rc.10",
42
+ "@xyo-network/diviner-wrapper": "^3.6.0-rc.10",
43
+ "@xyo-network/module-model": "^3.6.0-rc.10",
44
+ "@xyo-network/payload-builder": "^3.6.0-rc.10",
45
+ "@xyo-network/payload-model": "^3.6.0-rc.10"
45
46
  },
46
47
  "devDependencies": {
47
- "@xylabs/ts-scripts-yarn3": "^4.2.4",
48
- "@xylabs/tsconfig": "^4.2.4",
49
- "@xylabs/vitest-extended": "^4.4.9",
50
- "@xyo-network/account": "^3.5.2",
51
- "@xyo-network/archivist-memory": "^3.5.2",
52
- "@xyo-network/diviner-boundwitness-memory": "^3.5.2",
53
- "@xyo-network/diviner-payload-memory": "^3.5.2",
54
- "@xyo-network/manifest": "^3.5.2",
55
- "@xyo-network/module-factory-locator": "^3.5.2",
56
- "@xyo-network/node-memory": "^3.5.2",
48
+ "@xylabs/ts-scripts-yarn3": "^4.2.6",
49
+ "@xylabs/tsconfig": "^4.2.6",
50
+ "@xylabs/vitest-extended": "^4.4.21",
51
+ "@xyo-network/account": "^3.6.0-rc.10",
52
+ "@xyo-network/archivist-memory": "^3.6.0-rc.10",
53
+ "@xyo-network/diviner-boundwitness-memory": "^3.6.0-rc.10",
54
+ "@xyo-network/diviner-payload-memory": "^3.6.0-rc.10",
55
+ "@xyo-network/manifest": "^3.6.0-rc.10",
56
+ "@xyo-network/module-factory-locator": "^3.6.0-rc.10",
57
+ "@xyo-network/node-memory": "^3.6.0-rc.10",
57
58
  "typescript": "^5.7.2",
58
- "vitest": "^2.1.5"
59
+ "vitest": "^2.1.8"
59
60
  },
60
61
  "publishConfig": {
61
62
  "access": "public"
62
- }
63
+ },
64
+ "stableVersion": "3.5.2"
63
65
  }
package/src/Diviner.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { assertEx } from '@xylabs/assert'
2
2
  import type { Hash } from '@xylabs/hex'
3
+ import { toJson } from '@xylabs/object'
3
4
  import { ArchivistWrapper } from '@xyo-network/archivist-wrapper'
4
5
  import { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'
5
6
  import { isBoundWitness } from '@xyo-network/boundwitness-model'
@@ -11,8 +12,9 @@ import { DivinerWrapper } from '@xyo-network/diviner-wrapper'
11
12
  import type { ModuleState, StateDictionary } from '@xyo-network/module-model'
12
13
  import { isModuleState, ModuleStateSchema } from '@xyo-network/module-model'
13
14
  import { PayloadBuilder } from '@xyo-network/payload-builder'
14
- import type {
15
- Payload, Schema, WithMeta,
15
+ import {
16
+ type Payload, type Schema, SequenceConstants,
17
+ type WithStorageMeta,
16
18
  } from '@xyo-network/payload-model'
17
19
 
18
20
  import { StatefulDivinerConfigSchema } from './Config.ts'
@@ -40,7 +42,7 @@ export abstract class StatefulDiviner<
40
42
  /**
41
43
  * The last state
42
44
  */
43
- protected _lastState?: WithMeta<ModuleState<TState>>
45
+ protected _lastState?: ModuleState<TState>
44
46
 
45
47
  /**
46
48
  * Commit the internal state of the Diviner process. This is similar
@@ -49,9 +51,9 @@ export abstract class StatefulDiviner<
49
51
  * external stores.
50
52
  * @param nextState The state to commit
51
53
  */
52
- protected async commitState(nextState: WithMeta<ModuleState<TState>>) {
54
+ protected async commitState(nextState: ModuleState<TState>) {
53
55
  // Don't commit state if no state has changed
54
- if (nextState.state.offset === this._lastState?.state.offset) return
56
+ if (toJson(nextState.state) === toJson(this._lastState?.state)) return
55
57
  this._lastState = nextState
56
58
  const archivist = await this.getArchivistForStateStore()
57
59
  const [bw] = await new BoundWitnessBuilder().payload(nextState).signer(this.account).build()
@@ -95,7 +97,7 @@ export abstract class StatefulDiviner<
95
97
  * Retrieves the last state of the Diviner process. Used to recover state after
96
98
  * preemptions, reboots, etc.
97
99
  */
98
- protected async retrieveState(): Promise<WithMeta<ModuleState<TState>> | undefined> {
100
+ protected async retrieveState(): Promise<ModuleState<TState> | undefined> {
99
101
  if (this._lastState) return this._lastState
100
102
  let hash: Hash = ''
101
103
  const diviner = await this.getBoundWitnessDivinerForStateStore()
@@ -103,7 +105,7 @@ export abstract class StatefulDiviner<
103
105
  .fields({
104
106
  address: this.account.address,
105
107
  limit: 1,
106
- offset: 0,
108
+ cursor: SequenceConstants.minLocalSequence,
107
109
  order: 'desc',
108
110
  payload_schemas: [ModuleStateSchema],
109
111
  })
@@ -130,7 +132,7 @@ export abstract class StatefulDiviner<
130
132
  const archivist = await this.getArchivistForStateStore()
131
133
  const payload = (await archivist.get([hash])).find(isModuleState<TState>)
132
134
  if (payload) {
133
- return payload as WithMeta<ModuleState<TState>>
135
+ return payload as WithStorageMeta<ModuleState<TState>>
134
136
  }
135
137
  }
136
138
  return undefined
@@ -1,5 +1,6 @@
1
1
  import { assertEx } from '@xylabs/assert'
2
2
  import type { Hash } from '@xylabs/hex'
3
+ import { toJson } from '@xylabs/object'
3
4
  import { asArchivistInstance } from '@xyo-network/archivist-model'
4
5
  import { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'
5
6
  import { isBoundWitness } from '@xyo-network/boundwitness-model'
@@ -18,7 +19,7 @@ import {
18
19
  ModuleStateSchema,
19
20
  } from '@xyo-network/module-model'
20
21
  import { PayloadBuilder } from '@xyo-network/payload-builder'
21
- import type { WithMeta } from '@xyo-network/payload-model'
22
+ import { SequenceConstants, type WithStorageMeta } from '@xyo-network/payload-model'
22
23
 
23
24
  import type { StatefulDivinerConfig } from './Config.ts'
24
25
 
@@ -42,7 +43,7 @@ export const StatefulModuleMixin = <
42
43
  ModuleBase: TModule,
43
44
  ) => {
44
45
  abstract class StatefulModuleBase extends ModuleBase {
45
- _lastState?: WithMeta<ModuleState<TState>>
46
+ _lastState?: ModuleState<TState>
46
47
 
47
48
  /**
48
49
  * Commit the internal state of the Diviner process. This is similar
@@ -51,9 +52,9 @@ export const StatefulModuleMixin = <
51
52
  * external stores.
52
53
  * @param nextState The state to commit
53
54
  */
54
- async commitState(nextState: WithMeta<ModuleState<TState>>) {
55
+ async commitState(nextState: ModuleState<TState>) {
55
56
  // Don't commit state if no state has changed
56
- if (nextState.state.offset === this._lastState?.state.offset) return
57
+ if (toJson(nextState.state) === toJson(this._lastState?.state)) return
57
58
  this._lastState = nextState
58
59
  const archivist = await this.getArchivistForStore()
59
60
  // const [bw] = await new BoundWitnessBuilder().payload(nextState).signer(this.account).build()
@@ -107,7 +108,7 @@ export const StatefulModuleMixin = <
107
108
  * Retrieves the last state of the Diviner process. Used to recover state after
108
109
  * preemptions, reboots, etc.
109
110
  */
110
- async retrieveState(): Promise<WithMeta<ModuleState<TState>> | undefined> {
111
+ async retrieveState(): Promise<ModuleState<TState> | undefined> {
111
112
  if (this._lastState) return this._lastState
112
113
  let hash: Hash = ''
113
114
  const diviner = await this.getBoundWitnessDivinerForStore()
@@ -115,7 +116,7 @@ export const StatefulModuleMixin = <
115
116
  .fields({
116
117
  // address: this.account.address,
117
118
  limit: 1,
118
- offset: 0,
119
+ cursor: SequenceConstants.minLocalSequence,
119
120
  order: 'desc',
120
121
  payload_schemas: [ModuleStateSchema],
121
122
  })
@@ -142,7 +143,7 @@ export const StatefulModuleMixin = <
142
143
  const archivist = await this.getArchivistForStore()
143
144
  const payload = (await archivist.get([hash])).find(isModuleState<TState>)
144
145
  if (payload) {
145
- return payload as WithMeta<ModuleState<TState>>
146
+ return payload as WithStorageMeta<ModuleState<TState>>
146
147
  }
147
148
  }
148
149
  return undefined