@xyo-network/diviner-stateful 2.84.18 → 2.85.0
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.
- package/dist/browser/DivinerMixin.d.cts +20 -28
- package/dist/browser/DivinerMixin.d.cts.map +1 -1
- package/dist/browser/DivinerMixin.d.mts +20 -28
- package/dist/browser/DivinerMixin.d.mts.map +1 -1
- package/dist/browser/DivinerMixin.d.ts +20 -28
- package/dist/browser/DivinerMixin.d.ts.map +1 -1
- package/dist/browser/index.cjs +100 -71
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +103 -75
- package/dist/browser/index.js.map +1 -1
- package/dist/node/DivinerMixin.d.cts +20 -28
- package/dist/node/DivinerMixin.d.cts.map +1 -1
- package/dist/node/DivinerMixin.d.mts +20 -28
- package/dist/node/DivinerMixin.d.mts.map +1 -1
- package/dist/node/DivinerMixin.d.ts +20 -28
- package/dist/node/DivinerMixin.d.ts.map +1 -1
- package/dist/node/index.cjs +116 -85
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.js +119 -89
- package/dist/node/index.js.map +1 -1
- package/package.json +18 -18
package/dist/node/index.cjs
CHANGED
|
@@ -3,6 +3,8 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
8
10
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -16,6 +18,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
18
20
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
+
var __publicField = (obj, key, value) => {
|
|
22
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
23
|
+
return value;
|
|
24
|
+
};
|
|
19
25
|
|
|
20
26
|
// src/index.ts
|
|
21
27
|
var src_exports = {};
|
|
@@ -45,19 +51,18 @@ var import_diviner_wrapper = require("@xyo-network/diviner-wrapper");
|
|
|
45
51
|
var import_module_model = require("@xyo-network/module-model");
|
|
46
52
|
var import_payload_builder = require("@xyo-network/payload-builder");
|
|
47
53
|
var moduleName = "StatefulDiviner";
|
|
48
|
-
var
|
|
49
|
-
static configSchemas = [import_diviner_model.DivinerConfigSchema, StatefulDivinerConfigSchema];
|
|
54
|
+
var _StatefulDiviner = class _StatefulDiviner extends import_abstract_diviner.AbstractDiviner {
|
|
50
55
|
/**
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
* The last state
|
|
57
|
+
*/
|
|
53
58
|
_lastState;
|
|
54
59
|
/**
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
* Commit the internal state of the Diviner process. This is similar
|
|
61
|
+
* to a transaction completion in a database and should only be called
|
|
62
|
+
* when results have been successfully persisted to the appropriate
|
|
63
|
+
* external stores.
|
|
64
|
+
* @param nextState The state to commit
|
|
65
|
+
*/
|
|
61
66
|
async commitState(nextState) {
|
|
62
67
|
var _a;
|
|
63
68
|
if (nextState.state.offset === ((_a = this._lastState) == null ? void 0 : _a.state.offset))
|
|
@@ -65,13 +70,16 @@ var StatefulDiviner = class extends import_abstract_diviner.AbstractDiviner {
|
|
|
65
70
|
this._lastState = nextState;
|
|
66
71
|
const archivist = await this.getArchivistForStateStore();
|
|
67
72
|
const [bw] = await new import_boundwitness_builder.BoundWitnessBuilder().payload(nextState).witness(this.account).build();
|
|
68
|
-
await archivist.insert([
|
|
73
|
+
await archivist.insert([
|
|
74
|
+
bw,
|
|
75
|
+
nextState
|
|
76
|
+
]);
|
|
69
77
|
}
|
|
70
78
|
/**
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
* Retrieves the archivist for the specified store
|
|
80
|
+
* @param store The store to retrieve the archivist for
|
|
81
|
+
* @returns The archivist for the specified store
|
|
82
|
+
*/
|
|
75
83
|
async getArchivistForStateStore() {
|
|
76
84
|
var _a;
|
|
77
85
|
const name = (0, import_assert.assertEx)((_a = this.config) == null ? void 0 : _a.stateStore.archivist, () => `${moduleName}: Config for stateStore.archivist not specified`);
|
|
@@ -79,10 +87,10 @@ var StatefulDiviner = class extends import_abstract_diviner.AbstractDiviner {
|
|
|
79
87
|
return import_archivist_wrapper.ArchivistWrapper.wrap(mod, this.account);
|
|
80
88
|
}
|
|
81
89
|
/**
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
* Retrieves the BoundWitness Diviner for the specified store
|
|
91
|
+
* @param store The store to retrieve the BoundWitness Diviner for
|
|
92
|
+
* @returns The BoundWitness Diviner for the specified store
|
|
93
|
+
*/
|
|
86
94
|
async getBoundWitnessDivinerForStateStore() {
|
|
87
95
|
var _a;
|
|
88
96
|
const name = (0, import_assert.assertEx)((_a = this.config) == null ? void 0 : _a.stateStore.boundWitnessDiviner, () => `${moduleName}: Config for stateStore.boundWitnessDiviner not specified`);
|
|
@@ -90,10 +98,10 @@ var StatefulDiviner = class extends import_abstract_diviner.AbstractDiviner {
|
|
|
90
98
|
return import_diviner_wrapper.DivinerWrapper.wrap(mod, this.account);
|
|
91
99
|
}
|
|
92
100
|
/**
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
101
|
+
* Retrieves the Payload Diviner for the specified store
|
|
102
|
+
* @param store The store to retrieve the Payload Diviner for
|
|
103
|
+
* @returns The Payload Diviner for the specified store
|
|
104
|
+
*/
|
|
97
105
|
async getPayloadDivinerForStateStore() {
|
|
98
106
|
var _a, _b;
|
|
99
107
|
const name = (0, import_assert.assertEx)((_b = (_a = this.config) == null ? void 0 : _a.stateStore) == null ? void 0 : _b.payloadDiviner, () => `${moduleName}: Config for stateStore.payloadDiviner not specified`);
|
|
@@ -101,37 +109,45 @@ var StatefulDiviner = class extends import_abstract_diviner.AbstractDiviner {
|
|
|
101
109
|
return import_diviner_wrapper.DivinerWrapper.wrap(mod, this.account);
|
|
102
110
|
}
|
|
103
111
|
/**
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
112
|
+
* Retrieves the last state of the Diviner process. Used to recover state after
|
|
113
|
+
* preemptions, reboots, etc.
|
|
114
|
+
*/
|
|
107
115
|
async retrieveState() {
|
|
108
116
|
if (this._lastState)
|
|
109
117
|
return this._lastState;
|
|
110
118
|
let hash = "";
|
|
111
119
|
const diviner = await this.getBoundWitnessDivinerForStateStore();
|
|
112
|
-
const query = await new import_payload_builder.PayloadBuilder({
|
|
120
|
+
const query = await new import_payload_builder.PayloadBuilder({
|
|
121
|
+
schema: import_diviner_boundwitness_model.BoundWitnessDivinerQuerySchema
|
|
122
|
+
}).fields({
|
|
113
123
|
address: this.account.address,
|
|
114
124
|
limit: 1,
|
|
115
125
|
offset: 0,
|
|
116
126
|
order: "desc",
|
|
117
|
-
payload_schemas: [
|
|
127
|
+
payload_schemas: [
|
|
128
|
+
import_module_model.ModuleStateSchema
|
|
129
|
+
]
|
|
118
130
|
}).build();
|
|
119
|
-
const boundWitnesses = await diviner.divine([
|
|
131
|
+
const boundWitnesses = await diviner.divine([
|
|
132
|
+
query
|
|
133
|
+
]);
|
|
120
134
|
if (boundWitnesses.length > 0) {
|
|
121
135
|
const boundWitness = boundWitnesses[0];
|
|
122
136
|
if ((0, import_boundwitness_model.isBoundWitness)(boundWitness)) {
|
|
123
|
-
hash = boundWitness.addresses.map((address, index) => ({
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
);
|
|
137
|
+
hash = boundWitness.addresses.map((address, index) => ({
|
|
138
|
+
address,
|
|
139
|
+
index
|
|
140
|
+
})).filter(({ address }) => address === this.account.address).reduce((prev, curr) => {
|
|
141
|
+
var _a;
|
|
142
|
+
return ((_a = boundWitness.payload_schemas) == null ? void 0 : _a[curr == null ? void 0 : curr.index]) === import_module_model.ModuleStateSchema ? boundWitness.payload_hashes[curr == null ? void 0 : curr.index] : prev;
|
|
143
|
+
}, "");
|
|
130
144
|
}
|
|
131
145
|
}
|
|
132
146
|
if (hash) {
|
|
133
147
|
const archivist = await this.getArchivistForStateStore();
|
|
134
|
-
const payload = (await archivist.get([
|
|
148
|
+
const payload = (await archivist.get([
|
|
149
|
+
hash
|
|
150
|
+
])).find(import_module_model.isModuleState);
|
|
135
151
|
if (payload) {
|
|
136
152
|
return payload;
|
|
137
153
|
}
|
|
@@ -139,6 +155,12 @@ var StatefulDiviner = class extends import_abstract_diviner.AbstractDiviner {
|
|
|
139
155
|
return void 0;
|
|
140
156
|
}
|
|
141
157
|
};
|
|
158
|
+
__name(_StatefulDiviner, "StatefulDiviner");
|
|
159
|
+
__publicField(_StatefulDiviner, "configSchemas", [
|
|
160
|
+
import_diviner_model.DivinerConfigSchema,
|
|
161
|
+
StatefulDivinerConfigSchema
|
|
162
|
+
]);
|
|
163
|
+
var StatefulDiviner = _StatefulDiviner;
|
|
142
164
|
|
|
143
165
|
// src/DivinerMixin.ts
|
|
144
166
|
var import_assert2 = require("@xylabs/assert");
|
|
@@ -150,105 +172,114 @@ var import_diviner_model2 = require("@xyo-network/diviner-model");
|
|
|
150
172
|
var import_module_model2 = require("@xyo-network/module-model");
|
|
151
173
|
var import_payload_builder2 = require("@xyo-network/payload-builder");
|
|
152
174
|
var moduleName2 = "StatefulModuleMixin";
|
|
153
|
-
var StatefulModuleMixin = (ModuleBase) => {
|
|
154
|
-
|
|
175
|
+
var StatefulModuleMixin = /* @__PURE__ */ __name((ModuleBase) => {
|
|
176
|
+
var _a;
|
|
177
|
+
let StatefulModuleBase = (_a = class extends ModuleBase {
|
|
155
178
|
_lastState;
|
|
156
179
|
/**
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
180
|
+
* Commit the internal state of the Diviner process. This is similar
|
|
181
|
+
* to a transaction completion in a database and should only be called
|
|
182
|
+
* when results have been successfully persisted to the appropriate
|
|
183
|
+
* external stores.
|
|
184
|
+
* @param nextState The state to commit
|
|
185
|
+
*/
|
|
163
186
|
async commitState(nextState) {
|
|
164
|
-
var
|
|
165
|
-
if (nextState.state.offset === ((
|
|
187
|
+
var _a2;
|
|
188
|
+
if (nextState.state.offset === ((_a2 = this._lastState) == null ? void 0 : _a2.state.offset))
|
|
166
189
|
return;
|
|
167
190
|
this._lastState = nextState;
|
|
168
191
|
const archivist = await this.getArchivistForStore();
|
|
169
192
|
const [bw] = await new import_boundwitness_builder2.BoundWitnessBuilder().payload(nextState).build();
|
|
170
|
-
await archivist.insert([
|
|
193
|
+
await archivist.insert([
|
|
194
|
+
bw,
|
|
195
|
+
nextState
|
|
196
|
+
]);
|
|
171
197
|
}
|
|
172
198
|
/**
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
199
|
+
* Retrieves the archivist for the specified store
|
|
200
|
+
* @param store The store to retrieve the archivist for
|
|
201
|
+
* @returns The archivist for the specified store
|
|
202
|
+
*/
|
|
177
203
|
async getArchivistForStore() {
|
|
178
|
-
var
|
|
179
|
-
const name = (0, import_assert2.assertEx)((_b = (
|
|
204
|
+
var _a2, _b;
|
|
205
|
+
const name = (0, import_assert2.assertEx)((_b = (_a2 = this.config) == null ? void 0 : _a2.stateStore) == null ? void 0 : _b.archivist, () => `${moduleName2}: Config for stateStore.archivist not specified`);
|
|
180
206
|
const mod = (0, import_assert2.assertEx)(await this.resolve(name), () => `${moduleName2}: Failed to resolve stateStore.archivist`);
|
|
181
207
|
const instance = (0, import_archivist.asArchivistInstance)(mod);
|
|
182
208
|
return (0, import_assert2.assertEx)(instance, () => `${moduleName2}: Failed to wrap archivist instance`);
|
|
183
209
|
}
|
|
184
210
|
/**
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
211
|
+
* Retrieves the BoundWitness Diviner for the specified store
|
|
212
|
+
* @param store The store to retrieve the BoundWitness Diviner for
|
|
213
|
+
* @returns The BoundWitness Diviner for the specified store
|
|
214
|
+
*/
|
|
189
215
|
async getBoundWitnessDivinerForStore() {
|
|
190
|
-
var
|
|
191
|
-
const name = (0, import_assert2.assertEx)(
|
|
192
|
-
(_b = (_a = this.config) == null ? void 0 : _a.stateStore) == null ? void 0 : _b.boundWitnessDiviner,
|
|
193
|
-
() => `${moduleName2}: Config for stateStore.boundWitnessDiviner not specified`
|
|
194
|
-
);
|
|
216
|
+
var _a2, _b;
|
|
217
|
+
const name = (0, import_assert2.assertEx)((_b = (_a2 = this.config) == null ? void 0 : _a2.stateStore) == null ? void 0 : _b.boundWitnessDiviner, () => `${moduleName2}: Config for stateStore.boundWitnessDiviner not specified`);
|
|
195
218
|
const mod = (0, import_assert2.assertEx)(await this.resolve(name), () => `${moduleName2}: Failed to resolve stateStore.boundWitnessDiviner`);
|
|
196
219
|
const instance = (0, import_diviner_model2.asDivinerInstance)(mod);
|
|
197
220
|
return (0, import_assert2.assertEx)(instance, () => `${moduleName2}: Failed to wrap diviner instance`);
|
|
198
221
|
}
|
|
199
222
|
/**
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
223
|
+
* Retrieves the Payload Diviner for the specified store
|
|
224
|
+
* @param store The store to retrieve the Payload Diviner for
|
|
225
|
+
* @returns The Payload Diviner for the specified store
|
|
226
|
+
*/
|
|
204
227
|
async getPayloadDivinerForStateStore() {
|
|
205
|
-
var
|
|
206
|
-
const name = (0, import_assert2.assertEx)((_b = (
|
|
228
|
+
var _a2, _b;
|
|
229
|
+
const name = (0, import_assert2.assertEx)((_b = (_a2 = this.config) == null ? void 0 : _a2.stateStore) == null ? void 0 : _b.payloadDiviner, () => `${moduleName2}: Config for stateStore.payloadDiviner not specified`);
|
|
207
230
|
const mod = (0, import_assert2.assertEx)(await this.resolve(name), () => `${moduleName2}: Failed to resolve stateStore.payloadDiviner`);
|
|
208
231
|
const instance = (0, import_diviner_model2.asDivinerInstance)(mod);
|
|
209
232
|
return (0, import_assert2.assertEx)(instance, () => `${moduleName2}: Failed to wrap diviner instance`);
|
|
210
233
|
}
|
|
211
234
|
/**
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
235
|
+
* Retrieves the last state of the Diviner process. Used to recover state after
|
|
236
|
+
* preemptions, reboots, etc.
|
|
237
|
+
*/
|
|
215
238
|
async retrieveState() {
|
|
216
239
|
if (this._lastState)
|
|
217
240
|
return this._lastState;
|
|
218
241
|
let hash = "";
|
|
219
242
|
const diviner = await this.getBoundWitnessDivinerForStore();
|
|
220
|
-
const query = await new import_payload_builder2.PayloadBuilder({
|
|
243
|
+
const query = await new import_payload_builder2.PayloadBuilder({
|
|
244
|
+
schema: import_diviner_boundwitness_model2.BoundWitnessDivinerQuerySchema
|
|
245
|
+
}).fields({
|
|
221
246
|
// address: this.account.address,
|
|
222
247
|
limit: 1,
|
|
223
248
|
offset: 0,
|
|
224
249
|
order: "desc",
|
|
225
|
-
payload_schemas: [
|
|
250
|
+
payload_schemas: [
|
|
251
|
+
import_module_model2.ModuleStateSchema
|
|
252
|
+
]
|
|
226
253
|
}).build();
|
|
227
|
-
const boundWitnesses = await diviner.divine([
|
|
254
|
+
const boundWitnesses = await diviner.divine([
|
|
255
|
+
query
|
|
256
|
+
]);
|
|
228
257
|
if (boundWitnesses.length > 0) {
|
|
229
258
|
const boundWitness = boundWitnesses[0];
|
|
230
259
|
if ((0, import_boundwitness_model2.isBoundWitness)(boundWitness)) {
|
|
231
|
-
hash = boundWitness.addresses.map((address, index) => ({
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
);
|
|
260
|
+
hash = boundWitness.addresses.map((address, index) => ({
|
|
261
|
+
address,
|
|
262
|
+
index
|
|
263
|
+
})).reduce((prev, curr) => {
|
|
264
|
+
var _a2;
|
|
265
|
+
return ((_a2 = boundWitness.payload_schemas) == null ? void 0 : _a2[curr == null ? void 0 : curr.index]) === import_module_model2.ModuleStateSchema ? boundWitness.payload_hashes[curr == null ? void 0 : curr.index] : prev;
|
|
266
|
+
}, "");
|
|
238
267
|
}
|
|
239
268
|
}
|
|
240
269
|
if (hash) {
|
|
241
270
|
const archivist = await this.getArchivistForStore();
|
|
242
|
-
const payload = (await archivist.get([
|
|
271
|
+
const payload = (await archivist.get([
|
|
272
|
+
hash
|
|
273
|
+
])).find(import_module_model2.isModuleState);
|
|
243
274
|
if (payload) {
|
|
244
275
|
return payload;
|
|
245
276
|
}
|
|
246
277
|
}
|
|
247
278
|
return void 0;
|
|
248
279
|
}
|
|
249
|
-
}
|
|
280
|
+
}, __name(_a, "StatefulModuleBase"), _a);
|
|
250
281
|
return StatefulModuleBase;
|
|
251
|
-
};
|
|
282
|
+
}, "StatefulModuleMixin");
|
|
252
283
|
// Annotate the CommonJS export names for ESM import in node:
|
|
253
284
|
0 && (module.exports = {
|
|
254
285
|
StatefulDiviner,
|
package/dist/node/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/Schema.ts","../../src/Config.ts","../../src/Diviner.ts","../../src/DivinerMixin.ts"],"sourcesContent":["export * from './Config'\nexport * from './Diviner'\nexport * from './DivinerMixin'\nexport * from './Params'\nexport * from './Schema'\n","export const StatefulDivinerSchema = 'network.xyo.diviner.stateful' as const\nexport type StatefulDivinerSchema = typeof StatefulDivinerSchema\n","import { DivinerConfig } from '@xyo-network/diviner-model'\n\nimport { StatefulDivinerSchema } from './Schema'\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: string\n boundWitnessDiviner: string\n payloadDiviner: string\n }\n}>\n","import { assertEx } from '@xylabs/assert'\nimport { AbstractDiviner } from '@xyo-network/abstract-diviner'\nimport { ArchivistWrapper } from '@xyo-network/archivist-wrapper'\nimport { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'\nimport { isBoundWitness } from '@xyo-network/boundwitness-model'\nimport { BoundWitnessDivinerQueryPayload, BoundWitnessDivinerQuerySchema } from '@xyo-network/diviner-boundwitness-model'\nimport { DivinerConfigSchema, DivinerModule, DivinerModuleEventData } from '@xyo-network/diviner-model'\nimport { DivinerWrapper } from '@xyo-network/diviner-wrapper'\nimport { isModuleState, ModuleState, ModuleStateSchema, StateDictionary } from '@xyo-network/module-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Payload } from '@xyo-network/payload-model'\n\nimport { StatefulDivinerConfigSchema } from './Config'\nimport { StatefulDivinerParams } from './Params'\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<DivinerModule<TParams>, TIn, TOut> = DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut>,\n TState extends StateDictionary = StateDictionary,\n> extends AbstractDiviner<TParams, TIn, TOut, TEventData> {\n static override readonly configSchemas: string[] = [DivinerConfigSchema, 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 (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).witness(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: string = ''\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 '',\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\n }\n }\n return undefined\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { asArchivistInstance } from '@xyo-network/archivist'\nimport { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'\nimport { isBoundWitness } from '@xyo-network/boundwitness-model'\nimport { BoundWitnessDivinerQueryPayload, BoundWitnessDivinerQuerySchema } from '@xyo-network/diviner-boundwitness-model'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport {\n AnyConfigSchema,\n isModuleState,\n ModuleInstance,\n ModuleParams,\n ModuleState,\n ModuleStateSchema,\n StateDictionary,\n} from '@xyo-network/module-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\n\nimport { StatefulDivinerConfig } from './Config'\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 (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).witness(this.account).build()\n const [bw] = 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 * 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 * 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: string = ''\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 '',\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\n }\n }\n return undefined\n }\n }\n return StatefulModuleBase\n}\n"],"mappings":"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","names":["import_assert","import_boundwitness_builder","import_boundwitness_model","import_diviner_boundwitness_model","import_diviner_model","import_module_model","import_payload_builder","moduleName"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/Schema.ts","../../src/Config.ts","../../src/Diviner.ts","../../src/DivinerMixin.ts"],"sourcesContent":["export * from './Config'\nexport * from './Diviner'\nexport * from './DivinerMixin'\nexport * from './Params'\nexport * from './Schema'\n","export const StatefulDivinerSchema = 'network.xyo.diviner.stateful' as const\nexport type StatefulDivinerSchema = typeof StatefulDivinerSchema\n","import { DivinerConfig } from '@xyo-network/diviner-model'\n\nimport { StatefulDivinerSchema } from './Schema'\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: string\n boundWitnessDiviner: string\n payloadDiviner: string\n }\n}>\n","import { assertEx } from '@xylabs/assert'\nimport { AbstractDiviner } from '@xyo-network/abstract-diviner'\nimport { ArchivistWrapper } from '@xyo-network/archivist-wrapper'\nimport { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'\nimport { isBoundWitness } from '@xyo-network/boundwitness-model'\nimport { BoundWitnessDivinerQueryPayload, BoundWitnessDivinerQuerySchema } from '@xyo-network/diviner-boundwitness-model'\nimport { DivinerConfigSchema, DivinerModule, DivinerModuleEventData } from '@xyo-network/diviner-model'\nimport { DivinerWrapper } from '@xyo-network/diviner-wrapper'\nimport { isModuleState, ModuleState, ModuleStateSchema, StateDictionary } from '@xyo-network/module-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Payload } from '@xyo-network/payload-model'\n\nimport { StatefulDivinerConfigSchema } from './Config'\nimport { StatefulDivinerParams } from './Params'\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<DivinerModule<TParams>, TIn, TOut> = DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut>,\n TState extends StateDictionary = StateDictionary,\n> extends AbstractDiviner<TParams, TIn, TOut, TEventData> {\n static override readonly configSchemas: string[] = [DivinerConfigSchema, 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 (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).witness(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: string = ''\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 '',\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\n }\n }\n return undefined\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { asArchivistInstance } from '@xyo-network/archivist'\nimport { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'\nimport { isBoundWitness } from '@xyo-network/boundwitness-model'\nimport { BoundWitnessDivinerQueryPayload, BoundWitnessDivinerQuerySchema } from '@xyo-network/diviner-boundwitness-model'\nimport { asDivinerInstance } from '@xyo-network/diviner-model'\nimport {\n AnyConfigSchema,\n isModuleState,\n ModuleInstance,\n ModuleParams,\n ModuleState,\n ModuleStateSchema,\n StateDictionary,\n} from '@xyo-network/module-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\n\nimport { StatefulDivinerConfig } from './Config'\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 (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).witness(this.account).build()\n const [bw] = 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 * 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 * 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: string = ''\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 '',\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\n }\n }\n return undefined\n }\n }\n return StatefulModuleBase\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;ACAO,IAAMA,wBAAwB;;;ACO9B,IAAMC,8BAA8B,GAAGC,qBAAAA;;;ACP9C,oBAAyB;AACzB,8BAAgC;AAChC,+BAAiC;AACjC,kCAAoC;AACpC,gCAA+B;AAC/B,wCAAgF;AAChF,2BAA2E;AAC3E,6BAA+B;AAC/B,0BAA+E;AAC/E,6BAA+B;AAM/B,IAAMC,aAAa;AAKZ,IAAeC,mBAAf,MAAeA,yBAMZC,wCAAAA;;;;EAMEC;;;;;;;;EASV,MAAgBC,YAAYC,WAAgC;AAzC9D;AA2CI,QAAIA,UAAUC,MAAMC,aAAW,UAAKJ,eAAL,mBAAiBG,MAAMC;AAAQ;AAC9D,SAAKJ,aAAaE;AAClB,UAAMG,YAAY,MAAM,KAAKC,0BAAyB;AACtD,UAAM,CAACC,EAAAA,IAAM,MAAM,IAAIC,gDAAAA,EAAsBC,QAAQP,SAAAA,EAAWQ,QAAQ,KAAKC,OAAO,EAAEC,MAAK;AAC3F,UAAMP,UAAUQ,OAAO;MAACN;MAAIL;KAAU;EACxC;;;;;;EAOA,MAAgBI,4BAA4B;AAvD9C;AAwDI,UAAMQ,WAAOC,yBAAS,UAAKC,WAAL,mBAAaC,WAAWZ,WAAW,MAAM,GAAGR,UAAAA,iDAA2D;AAC7H,UAAMqB,UAAMH,wBAAS,MAAM,KAAKI,QAAQL,IAAAA,GAAO,MAAM,GAAGjB,UAAAA,0CAAoD;AAC5G,WAAOuB,0CAAiBC,KAAKH,KAAK,KAAKP,OAAO;EAChD;;;;;;EAOA,MAAgBW,sCAAsC;AAlExD;AAmEI,UAAMR,WAAOC,yBAAS,UAAKC,WAAL,mBAAaC,WAAWM,qBAAqB,MAAM,GAAG1B,UAAAA,2DAAqE;AACjJ,UAAMqB,UAAMH,wBAAS,MAAM,KAAKI,QAAQL,IAAAA,GAAO,MAAM,GAAGjB,UAAAA,oDAA8D;AACtH,WAAO2B,sCAAeH,KAAKH,KAAK,KAAKP,OAAO;EAC9C;;;;;;EAOA,MAAgBc,iCAAiC;AA7EnD;AA8EI,UAAMX,WAAOC,yBAAS,gBAAKC,WAAL,mBAAaC,eAAb,mBAAyBS,gBAAgB,MAAM,GAAG7B,UAAAA,sDAAgE;AACxI,UAAMqB,UAAMH,wBAAS,MAAM,KAAKI,QAAQL,IAAAA,GAAO,MAAM,GAAGjB,UAAAA,+CAAyD;AACjH,WAAO2B,sCAAeH,KAAKH,KAAK,KAAKP,OAAO;EAC9C;;;;;EAMA,MAAgBgB,gBAA0D;AACxE,QAAI,KAAK3B;AAAY,aAAO,KAAKA;AACjC,QAAI4B,OAAe;AACnB,UAAMC,UAAU,MAAM,KAAKP,oCAAmC;AAC9D,UAAMQ,QAAQ,MAAM,IAAIC,sCAAgD;MAAEC,QAAQC;IAA+B,CAAA,EAC9GC,OAAO;MACNC,SAAS,KAAKxB,QAAQwB;MACtBC,OAAO;MACPhC,QAAQ;MACRiC,OAAO;MACPC,iBAAiB;QAACC;;IACpB,CAAA,EACC3B,MAAK;AACR,UAAM4B,iBAAiB,MAAMX,QAAQY,OAAO;MAACX;KAAM;AACnD,QAAIU,eAAeE,SAAS,GAAG;AAC7B,YAAMC,eAAeH,eAAe,CAAA;AACpC,cAAII,0CAAeD,YAAAA,GAAe;AAEhCf,eAAOe,aAAaE,UACjBC,IAAI,CAACX,SAASY,WAAW;UAAEZ;UAASY;QAAM,EAAA,EAC1CC,OAAO,CAAC,EAAEb,QAAO,MAAOA,YAAY,KAAKxB,QAAQwB,OAAO,EAExDc,OACC,CAACC,MAAMC,SAAAA;AA9GnB;AA8G6BR,qCAAaL,oBAAbK,mBAA+BQ,6BAAMJ,YAAWR,wCAAoBI,aAAaS,eAAeD,6BAAMJ,KAAAA,IAASG;WAChI,EAAA;MAEN;IACF;AAGA,QAAItB,MAAM;AAER,YAAMvB,YAAY,MAAM,KAAKC,0BAAyB;AACtD,YAAMG,WAAW,MAAMJ,UAAUgD,IAAI;QAACzB;OAAK,GAAG0B,KAAKC,iCAAAA;AACnD,UAAI9C,SAAS;AACX,eAAOA;MACT;IACF;AACA,WAAO+C;EACT;AACF;AArGUzD;AACR,cAPoBD,kBAOK2D,iBAA0B;EAACC;EAAqBC;;AAPpE,IAAe7D,kBAAf;;;ACpBP,IAAA8D,iBAAyB;AACzB,uBAAoC;AACpC,IAAAC,+BAAoC;AACpC,IAAAC,6BAA+B;AAC/B,IAAAC,qCAAgF;AAChF,IAAAC,wBAAkC;AAClC,IAAAC,uBAQO;AACP,IAAAC,0BAA+B;AAS/B,IAAMC,cAAa;AAOZ,IAAMC,sBAAsB,wBAKjCC,eAAAA;AApCF;AAsCE,MAAeC,sBAAf,mBAA0CD,WAAAA;IACxCE;;;;;;;;IASA,MAAMC,YAAYC,WAAgC;AAhDtD,UAAAC;AAkDM,UAAID,UAAUE,MAAMC,aAAWF,MAAA,KAAKH,eAAL,gBAAAG,IAAiBC,MAAMC;AAAQ;AAC9D,WAAKL,aAAaE;AAClB,YAAMI,YAAY,MAAM,KAAKC,qBAAoB;AAEjD,YAAM,CAACC,EAAAA,IAAM,MAAM,IAAIC,iDAAAA,EAAsBC,QAAQR,SAAAA,EAAWS,MAAK;AACrE,YAAML,UAAUM,OAAO;QAACJ;QAAIN;OAAU;IACxC;;;;;;IAOA,MAAMK,uBAAuB;AA/DjC,UAAAJ,KAAA;AAgEM,YAAMU,WAAOC,0BAAS,MAAAX,MAAA,KAAKY,WAAL,gBAAAZ,IAAaa,eAAb,mBAAyBV,WAAW,MAAM,GAAGV,WAAAA,iDAA2D;AAC9H,YAAMqB,UAAMH,yBAAS,MAAM,KAAKI,QAAQL,IAAAA,GAAO,MAAM,GAAGjB,WAAAA,0CAAoD;AAE5G,YAAMuB,eAAWC,sCAAoBH,GAAAA;AACrC,iBAAOH,yBAASK,UAAU,MAAM,GAAGvB,WAAAA,qCAA+C;IACpF;;;;;;IAOA,MAAMyB,iCAAiC;AA5E3C,UAAAlB,KAAA;AA6EM,YAAMU,WAAOC,0BACX,MAAAX,MAAA,KAAKY,WAAL,gBAAAZ,IAAaa,eAAb,mBAAyBM,qBACzB,MAAM,GAAG1B,WAAAA,2DAAqE;AAEhF,YAAMqB,UAAMH,yBAAS,MAAM,KAAKI,QAAQL,IAAAA,GAAO,MAAM,GAAGjB,WAAAA,oDAA8D;AAEtH,YAAMuB,eAAWI,yCAAkBN,GAAAA;AACnC,iBAAOH,yBAASK,UAAU,MAAM,GAAGvB,WAAAA,mCAA6C;IAClF;;;;;;IAMA,MAAM4B,iCAAiC;AA3F3C,UAAArB,KAAA;AA4FM,YAAMU,WAAOC,0BAAS,MAAAX,MAAA,KAAKY,WAAL,gBAAAZ,IAAaa,eAAb,mBAAyBS,gBAAgB,MAAM,GAAG7B,WAAAA,sDAAgE;AACxI,YAAMqB,UAAMH,yBAAS,MAAM,KAAKI,QAAQL,IAAAA,GAAO,MAAM,GAAGjB,WAAAA,+CAAyD;AAEjH,YAAMuB,eAAWI,yCAAkBN,GAAAA;AACnC,iBAAOH,yBAASK,UAAU,MAAM,GAAGvB,WAAAA,mCAA6C;IAClF;;;;;IAKA,MAAM8B,gBAA0D;AAC9D,UAAI,KAAK1B;AAAY,eAAO,KAAKA;AACjC,UAAI2B,OAAe;AACnB,YAAMC,UAAU,MAAM,KAAKP,+BAA8B;AACzD,YAAMQ,QAAQ,MAAM,IAAIC,uCAAgD;QAAEC,QAAQC;MAA+B,CAAA,EAC9GC,OAAO;;QAENC,OAAO;QACP7B,QAAQ;QACR8B,OAAO;QACPC,iBAAiB;UAACC;;MACpB,CAAA,EACC1B,MAAK;AACR,YAAM2B,iBAAiB,MAAMV,QAAQW,OAAO;QAACV;OAAM;AACnD,UAAIS,eAAeE,SAAS,GAAG;AAC7B,cAAMC,eAAeH,eAAe,CAAA;AACpC,gBAAII,2CAAeD,YAAAA,GAAe;AAEhCd,iBAAOc,aAAaE,UACjBC,IAAI,CAACC,SAASC,WAAW;YAAED;YAASC;UAAM,EAAA,EAG1CC,OACC,CAACC,MAAMC,SAAAA;AA7HrB,gBAAA9C;AA6H+BsC,qBAAAA,MAAAA,aAAaL,oBAAbK,gBAAAA,IAA+BQ,6BAAMH,YAAWT,yCAAoBI,aAAaS,eAAeD,6BAAMH,KAAAA,IAASE;aAChI,EAAA;QAEN;MACF;AAGA,UAAIrB,MAAM;AAER,cAAMrB,YAAY,MAAM,KAAKC,qBAAoB;AACjD,cAAMG,WAAW,MAAMJ,UAAU6C,IAAI;UAACxB;SAAK,GAAGyB,KAAKC,kCAAAA;AACnD,YAAI3C,SAAS;AACX,iBAAOA;QACT;MACF;AACA,aAAO4C;IACT;EACF,GAxG0CxD,kCAA1C;AAyGA,SAAOC;AACT,GAjHmC;","names":["StatefulDivinerSchema","StatefulDivinerConfigSchema","StatefulDivinerSchema","moduleName","StatefulDiviner","AbstractDiviner","_lastState","commitState","nextState","state","offset","archivist","getArchivistForStateStore","bw","BoundWitnessBuilder","payload","witness","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","configSchemas","DivinerConfigSchema","StatefulDivinerConfigSchema","import_assert","import_boundwitness_builder","import_boundwitness_model","import_diviner_boundwitness_model","import_diviner_model","import_module_model","import_payload_builder","moduleName","StatefulModuleMixin","ModuleBase","StatefulModuleBase","_lastState","commitState","nextState","_a","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"]}
|