@xyo-network/archivist-storage 3.3.1 → 3.3.3

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,10 +1,13 @@
1
1
  import type { Hash } from '@xylabs/hex';
2
2
  import type { Promisable, PromisableArray } from '@xylabs/promise';
3
3
  import { AbstractArchivist } from '@xyo-network/archivist-abstract';
4
- import type { ArchivistConfig, ArchivistInstance, ArchivistModuleEventData, ArchivistParams } from '@xyo-network/archivist-model';
4
+ import type { ArchivistConfig, ArchivistInstance, ArchivistModuleEventData, ArchivistNextOptions, ArchivistParams } from '@xyo-network/archivist-model';
5
5
  import type { BoundWitness } from '@xyo-network/boundwitness-model';
6
6
  import type { AnyConfigSchema } from '@xyo-network/module-model';
7
7
  import type { Payload, PayloadWithMeta, Schema, WithMeta } from '@xyo-network/payload-model';
8
+ type WithStorageMeta<T extends Payload = Payload> = WithMeta<T> & {
9
+ _timestamp: number;
10
+ };
8
11
  export type StorageArchivistConfigSchema = 'network.xyo.archivist.storage.config';
9
12
  export declare const StorageArchivistConfigSchema: StorageArchivistConfigSchema;
10
13
  export type StorageArchivistConfig = ArchivistConfig<{
@@ -31,8 +34,13 @@ export declare class StorageArchivist<TParams extends StorageArchivistParams = S
31
34
  protected clearHandler(): void | Promise<void>;
32
35
  protected commitHandler(): Promise<WithMeta<BoundWitness>[]>;
33
36
  protected deleteHandler(hashes: Hash[]): Promise<Hash[]>;
37
+ protected getFromOffset(order?: 'asc' | 'desc', limit?: number, offset?: Hash): WithStorageMeta[];
34
38
  protected getHandler(hashes: string[]): Promisable<PayloadWithMeta[]>;
35
39
  protected insertHandler(payloads: Payload[]): Promise<PayloadWithMeta[]>;
40
+ protected nextHandler(options?: ArchivistNextOptions): Promisable<PayloadWithMeta[]>;
36
41
  protected startHandler(): Promise<boolean>;
42
+ private addStorageMeta;
43
+ private removeStorageMeta;
37
44
  }
45
+ export {};
38
46
  //# sourceMappingURL=StorageArchivist.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"StorageArchivist.d.ts","sourceRoot":"","sources":["../../src/StorageArchivist.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAElE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AACnE,OAAO,KAAK,EACV,eAAe,EAEf,iBAAiB,EACjB,wBAAwB,EACxB,eAAe,EAChB,MAAM,8BAA8B,CAAA;AAQrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAEhE,OAAO,KAAK,EACV,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,EAC3C,MAAM,4BAA4B,CAAA;AAMnC,MAAM,MAAM,4BAA4B,GAAG,sCAAsC,CAAA;AACjF,eAAO,MAAM,4BAA4B,EAAE,4BAAqE,CAAA;AAEhH,MAAM,MAAM,sBAAsB,GAAG,eAAe,CAAC;IACnD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,4BAA4B,CAAA;IACpC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;CACpC,CAAC,CAAA;AAEF,MAAM,MAAM,sBAAsB,GAAG,eAAe,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC,CAAA;AAC7F,qBAAa,gBAAgB,CAC3B,OAAO,SAAS,sBAAsB,GAAG,sBAAsB,EAC/D,UAAU,SAAS,wBAAwB,GAAG,wBAAwB,CAEtE,SAAQ,iBAAiB,CAAC,OAAO,EAAE,UAAU,CAC7C,YAAW,iBAAiB;IAC5B,gBAAyB,aAAa,EAAE,MAAM,EAAE,CAAyD;IACzG,gBAAyB,mBAAmB,EAAE,MAAM,CAA+B;IAEnF,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAuB;IAEvC,IAAI,UAAU,WAEb;IAED,IAAI,YAAY,WAEf;IAED,IAAI,SAAS,WAEZ;IAED,IAAa,OAAO,IAAI,MAAM,EAAE,CAS/B;IAED,IAAI,IAAI,iCAEP;IAGD,OAAO,KAAK,cAAc,GAGzB;IAGD,OAAO,KAAK,OAAO,GAGlB;cAoBkB,UAAU,IAAI,eAAe,CAAC,eAAe,CAAC;cAe9C,YAAY,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;cAM9B,aAAa,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;cAgBlD,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;cAWpD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,eAAe,EAAE,CAAC;cAiBrD,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;cAW9D,YAAY;CAItC"}
1
+ {"version":3,"file":"StorageArchivist.d.ts","sourceRoot":"","sources":["../../src/StorageArchivist.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAElE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AACnE,OAAO,KAAK,EACV,eAAe,EAEf,iBAAiB,EACjB,wBAAwB,EACxB,oBAAoB,EACpB,eAAe,EAChB,MAAM,8BAA8B,CAAA;AAQrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAEhE,OAAO,KAAK,EACV,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,EAC3C,MAAM,4BAA4B,CAAA;AAMnC,KAAK,eAAe,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAA;AAExF,MAAM,MAAM,4BAA4B,GAAG,sCAAsC,CAAA;AACjF,eAAO,MAAM,4BAA4B,EAAE,4BAAqE,CAAA;AAEhH,MAAM,MAAM,sBAAsB,GAAG,eAAe,CAAC;IACnD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,4BAA4B,CAAA;IACpC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;CACpC,CAAC,CAAA;AAEF,MAAM,MAAM,sBAAsB,GAAG,eAAe,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC,CAAA;AAC7F,qBAAa,gBAAgB,CAC3B,OAAO,SAAS,sBAAsB,GAAG,sBAAsB,EAC/D,UAAU,SAAS,wBAAwB,GAAG,wBAAwB,CAEtE,SAAQ,iBAAiB,CAAC,OAAO,EAAE,UAAU,CAC7C,YAAW,iBAAiB;IAC5B,gBAAyB,aAAa,EAAE,MAAM,EAAE,CAAyD;IACzG,gBAAyB,mBAAmB,EAAE,MAAM,CAA+B;IAEnF,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAuB;IAEvC,IAAI,UAAU,WAEb;IAED,IAAI,YAAY,WAEf;IAED,IAAI,SAAS,WAEZ;IAED,IAAa,OAAO,IAAI,MAAM,EAAE,CAS/B;IAED,IAAI,IAAI,iCAEP;IAGD,OAAO,KAAK,cAAc,GAGzB;IAGD,OAAO,KAAK,OAAO,GAGlB;cAEkB,UAAU,IAAI,eAAe,CAAC,eAAe,CAAC;cAiB9C,YAAY,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;cAM9B,aAAa,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;cAgBlD,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAWvE,SAAS,CAAC,aAAa,CACrB,KAAK,GAAE,KAAK,GAAG,MAAc,EAC7B,KAAK,GAAE,MAAW,EAClB,MAAM,CAAC,EAAE,IAAI,GACZ,eAAe,EAAE;cAyBD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,eAAe,EAAE,CAAC;cAiBrD,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;cAcpE,WAAW,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,UAAU,CAAC,eAAe,EAAE,CAAC;cAOpE,YAAY;IAKrC,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,iBAAiB;CAK1B"}
@@ -54,23 +54,6 @@ var StorageArchivist = class extends AbstractArchivist {
54
54
  this._storage = this._storage ?? storeTypes[this.type].namespace(this.namespace);
55
55
  return this._storage;
56
56
  }
57
- /* override async loadAccount(account?: AccountInstance, persistAccount?: boolean, privateStorage?: StoreBase, _logger?: Logger) {
58
- if (!this._account) {
59
- if (persistAccount) {
60
- const privateKey = privateStorage?.get('privateKey')
61
- if (privateKey) {
62
- try {
63
- this._account = await Account.create({ privateKey })
64
- return this._account
65
- } catch (ex) {
66
- console.error(`Error reading Account from storage [${ex}] - Recreating Account`)
67
- privateStorage?.remove('privateKey')
68
- }
69
- }
70
- }
71
- }
72
- return await super.loadAccount()
73
- } */
74
57
  allHandler() {
75
58
  const found = /* @__PURE__ */ new Set();
76
59
  this.logger?.log(`this.storage.length: ${this.storage.length}`);
@@ -81,7 +64,7 @@ var StorageArchivist = class extends AbstractArchivist {
81
64
  found.add(payload.$hash);
82
65
  return true;
83
66
  }
84
- });
67
+ }).sort((a, b) => a._timestamp - b._timestamp).map((payload) => this.removeStorageMeta(payload));
85
68
  }
86
69
  clearHandler() {
87
70
  this.logger?.log(`this.storage.length: ${this.storage.length}`);
@@ -110,6 +93,27 @@ var StorageArchivist = class extends AbstractArchivist {
110
93
  return hash;
111
94
  }))).filter(exists);
112
95
  }
96
+ getFromOffset(order = "asc", limit = 10, offset) {
97
+ const offsetHash = offset ? this.storage.get(offset)?.$hash : void 0;
98
+ const found = /* @__PURE__ */ new Set();
99
+ const payloads = Object.entries(this.storage.getAll()).map(([, value]) => value).filter((payload) => {
100
+ if (found.has(payload.$hash)) {
101
+ return false;
102
+ } else {
103
+ found.add(payload.$hash);
104
+ return true;
105
+ }
106
+ }).sort((a, b) => {
107
+ return order === "asc" ? a._timestamp - b._timestamp : b._timestamp - a._timestamp;
108
+ });
109
+ if (offsetHash) {
110
+ const index = payloads.findIndex((payload) => payload.$hash === offsetHash);
111
+ if (index !== -1) {
112
+ return payloads.slice(index + 1, index + 1 + limit);
113
+ }
114
+ }
115
+ return payloads.slice(0, limit);
116
+ }
113
117
  getHandler(hashes) {
114
118
  const found = /* @__PURE__ */ new Set();
115
119
  return hashes.map((hash) => {
@@ -121,22 +125,39 @@ var StorageArchivist = class extends AbstractArchivist {
121
125
  found.add(payload.$hash);
122
126
  return true;
123
127
  }
124
- });
128
+ }).map((payload) => this.removeStorageMeta(payload));
125
129
  }
126
130
  async insertHandler(payloads) {
131
+ let timestamp = Date.now();
127
132
  const pairs = await PayloadBuilder.hashPairs(payloads);
128
133
  return pairs.map(([payload, hash]) => {
129
- const value = JSON.stringify(payload);
134
+ const storagePayload = this.addStorageMeta(payload, timestamp++);
135
+ const value = JSON.stringify(storagePayload);
136
+ console.log("insert.storagePayloads:", storagePayload);
130
137
  assertEx(value.length < this.maxEntrySize, () => `Payload too large [${hash}, ${value.length}]`);
131
- this.storage.set(hash, payload);
132
- this.storage.set(payload.$hash, payload);
138
+ this.storage.set(hash, storagePayload);
139
+ this.storage.set(payload.$hash, storagePayload);
133
140
  return payload;
134
141
  });
135
142
  }
143
+ nextHandler(options) {
144
+ const { limit, offset, order } = options ?? {};
145
+ return this.getFromOffset(order, limit ?? 10, offset);
146
+ }
136
147
  async startHandler() {
137
148
  await super.startHandler();
138
149
  return true;
139
150
  }
151
+ addStorageMeta(payload, _timestamp) {
152
+ return {
153
+ ...payload,
154
+ _timestamp
155
+ };
156
+ }
157
+ removeStorageMeta(payload) {
158
+ const { _timestamp, ...rest } = payload;
159
+ return rest;
160
+ }
140
161
  };
141
162
  export {
142
163
  StorageArchivist,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/StorageArchivist.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport { exists } from '@xylabs/exists'\nimport type { Hash } from '@xylabs/hex'\nimport type { Promisable, PromisableArray } from '@xylabs/promise'\nimport { fulfilled } from '@xylabs/promise'\nimport { AbstractArchivist } from '@xyo-network/archivist-abstract'\nimport type {\n ArchivistConfig,\n ArchivistInsertQuery,\n ArchivistInstance,\n ArchivistModuleEventData,\n ArchivistParams,\n} from '@xyo-network/archivist-model'\nimport {\n ArchivistAllQuerySchema,\n ArchivistClearQuerySchema,\n ArchivistCommitQuerySchema,\n ArchivistDeleteQuerySchema,\n ArchivistInsertQuerySchema,\n} from '@xyo-network/archivist-model'\nimport type { BoundWitness } from '@xyo-network/boundwitness-model'\nimport type { AnyConfigSchema } from '@xyo-network/module-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport type {\n Payload, PayloadWithMeta, Schema, WithMeta,\n} from '@xyo-network/payload-model'\nimport type { StoreBase, StoreType } from 'store2'\nimport store from 'store2'\n\nconst storeTypes = store as unknown as StoreType\n\nexport type StorageArchivistConfigSchema = 'network.xyo.archivist.storage.config'\nexport const StorageArchivistConfigSchema: StorageArchivistConfigSchema = 'network.xyo.archivist.storage.config'\n\nexport type StorageArchivistConfig = ArchivistConfig<{\n maxEntries?: number\n maxEntrySize?: number\n namespace?: string\n schema: StorageArchivistConfigSchema\n type?: 'local' | 'session' | 'page'\n}>\n\nexport type StorageArchivistParams = ArchivistParams<AnyConfigSchema<StorageArchivistConfig>>\nexport class StorageArchivist<\n TParams extends StorageArchivistParams = StorageArchivistParams,\n TEventData extends ArchivistModuleEventData = ArchivistModuleEventData,\n>\n extends AbstractArchivist<TParams, TEventData>\n implements ArchivistInstance {\n static override readonly configSchemas: Schema[] = [...super.configSchemas, StorageArchivistConfigSchema]\n static override readonly defaultConfigSchema: Schema = StorageArchivistConfigSchema\n\n private _privateStorage: StoreBase | undefined\n private _storage: StoreBase | undefined\n\n get maxEntries() {\n return this.config?.maxEntries ?? 1000\n }\n\n get maxEntrySize() {\n return this.config?.maxEntrySize ?? 16_000\n }\n\n get namespace() {\n return this.config?.namespace ?? 'xyo-archivist'\n }\n\n override get queries(): string[] {\n return [\n ArchivistAllQuerySchema,\n ArchivistDeleteQuerySchema,\n ArchivistClearQuerySchema,\n ArchivistInsertQuerySchema,\n ArchivistCommitQuerySchema,\n ...super.queries,\n ]\n }\n\n get type() {\n return this.config?.type ?? 'local'\n }\n\n /* This has to be a getter so that it can access it during construction */\n private get privateStorage(): StoreBase {\n this._privateStorage = this._storage ?? storeTypes[this.type].namespace(`${this.namespace}|private`)\n return this._privateStorage\n }\n\n /* This has to be a getter so that it can access it during construction */\n private get storage(): StoreBase {\n this._storage = this._storage ?? storeTypes[this.type].namespace(this.namespace)\n return this._storage\n }\n\n /* override async loadAccount(account?: AccountInstance, persistAccount?: boolean, privateStorage?: StoreBase, _logger?: Logger) {\n if (!this._account) {\n if (persistAccount) {\n const privateKey = privateStorage?.get('privateKey')\n if (privateKey) {\n try {\n this._account = await Account.create({ privateKey })\n return this._account\n } catch (ex) {\n console.error(`Error reading Account from storage [${ex}] - Recreating Account`)\n privateStorage?.remove('privateKey')\n }\n }\n }\n }\n return await super.loadAccount()\n } */\n\n protected override allHandler(): PromisableArray<PayloadWithMeta> {\n const found = new Set<string>()\n this.logger?.log(`this.storage.length: ${this.storage.length}`)\n return Object.entries(this.storage.getAll())\n .map(([, value]) => value)\n .filter((payload) => {\n if (found.has(payload.$hash)) {\n return false\n } else {\n found.add(payload.$hash)\n return true\n }\n })\n }\n\n protected override clearHandler(): void | Promise<void> {\n this.logger?.log(`this.storage.length: ${this.storage.length}`)\n this.storage.clear()\n return this.emit('cleared', { mod: this })\n }\n\n protected override async commitHandler(): Promise<WithMeta<BoundWitness>[]> {\n this.logger?.log(`this.storage.length: ${this.storage.length}`)\n const payloads = await this.all()\n assertEx(payloads.length > 0, () => 'Nothing to commit')\n const settled = (await Promise.allSettled(\n Object.values((await this.parentArchivists()).commit ?? [])?.map(async (parent) => {\n const queryPayload: ArchivistInsertQuery = { schema: ArchivistInsertQuerySchema }\n const query = await this.bindQuery(queryPayload, payloads)\n return (await parent?.query(query[0], query[1]))?.[0]\n }),\n )).filter(exists)\n // TODO - rather than clear, delete the payloads that come back as successfully inserted\n await this.clear()\n return (settled.filter(fulfilled).map(result => result.value)).filter(exists)\n }\n\n protected override async deleteHandler(hashes: Hash[]): Promise<Hash[]> {\n return (\n await Promise.all(\n hashes.map((hash) => {\n this.storage.remove(hash)\n return hash\n }),\n )\n ).filter(exists)\n }\n\n protected override getHandler(hashes: string[]): Promisable<PayloadWithMeta[]> {\n const found = new Set<string>()\n return (\n hashes.map((hash) => {\n return this.storage.get(hash)\n })\n ).filter(exists)\n .filter((payload) => {\n if (found.has(payload.$hash)) {\n return false\n } else {\n found.add(payload.$hash)\n return true\n }\n })\n }\n\n protected override async insertHandler(payloads: Payload[]): Promise<PayloadWithMeta[]> {\n const pairs = await PayloadBuilder.hashPairs(payloads)\n return pairs.map(([payload, hash]) => {\n const value = JSON.stringify(payload)\n assertEx(value.length < this.maxEntrySize, () => `Payload too large [${hash}, ${value.length}]`)\n this.storage.set(hash, payload)\n this.storage.set(payload.$hash, payload)\n return payload\n })\n }\n\n protected override async startHandler() {\n await super.startHandler()\n return true\n }\n}\n"],"mappings":";;;;AAAA,SAASA,gBAAgB;AACzB,SAASC,cAAc;AAGvB,SAASC,iBAAiB;AAC1B,SAASC,yBAAyB;AAQlC,SACEC,yBACAC,2BACAC,4BACAC,4BACAC,kCACK;AAGP,SAASC,sBAAsB;AAK/B,OAAOC,WAAW;AAElB,IAAMC,aAAaC;AAGZ,IAAMC,+BAA6D;AAWnE,IAAMC,mBAAN,cAIGC,kBAAAA;EA/CV,OA+CUA;;;EAER,OAAyBC,gBAA0B;OAAI,MAAMA;IAAeH;;EAC5E,OAAyBI,sBAA8BJ;EAE/CK;EACAC;EAER,IAAIC,aAAa;AACf,WAAO,KAAKC,QAAQD,cAAc;EACpC;EAEA,IAAIE,eAAe;AACjB,WAAO,KAAKD,QAAQC,gBAAgB;EACtC;EAEA,IAAIC,YAAY;AACd,WAAO,KAAKF,QAAQE,aAAa;EACnC;EAEA,IAAaC,UAAoB;AAC/B,WAAO;MACLC;MACAC;MACAC;MACAC;MACAC;SACG,MAAML;;EAEb;EAEA,IAAIM,OAAO;AACT,WAAO,KAAKT,QAAQS,QAAQ;EAC9B;;EAGA,IAAYC,iBAA4B;AACtC,SAAKb,kBAAkB,KAAKC,YAAYR,WAAW,KAAKmB,IAAI,EAAEP,UAAU,GAAG,KAAKA,SAAS,UAAU;AACnG,WAAO,KAAKL;EACd;;EAGA,IAAYc,UAAqB;AAC/B,SAAKb,WAAW,KAAKA,YAAYR,WAAW,KAAKmB,IAAI,EAAEP,UAAU,KAAKA,SAAS;AAC/E,WAAO,KAAKJ;EACd;;;;;;;;;;;;;;;;;;EAoBmBc,aAA+C;AAChE,UAAMC,QAAQ,oBAAIC,IAAAA;AAClB,SAAKC,QAAQC,IAAI,wBAAwB,KAAKL,QAAQM,MAAM,EAAE;AAC9D,WAAOC,OAAOC,QAAQ,KAAKR,QAAQS,OAAM,CAAA,EACtCC,IAAI,CAAC,CAAA,EAAGC,KAAAA,MAAWA,KAAAA,EACnBC,OAAO,CAACC,YAAAA;AACP,UAAIX,MAAMY,IAAID,QAAQE,KAAK,GAAG;AAC5B,eAAO;MACT,OAAO;AACLb,cAAMc,IAAIH,QAAQE,KAAK;AACvB,eAAO;MACT;IACF,CAAA;EACJ;EAEmBE,eAAqC;AACtD,SAAKb,QAAQC,IAAI,wBAAwB,KAAKL,QAAQM,MAAM,EAAE;AAC9D,SAAKN,QAAQkB,MAAK;AAClB,WAAO,KAAKC,KAAK,WAAW;MAAEC,KAAK;IAAK,CAAA;EAC1C;EAEA,MAAyBC,gBAAmD;AAC1E,SAAKjB,QAAQC,IAAI,wBAAwB,KAAKL,QAAQM,MAAM,EAAE;AAC9D,UAAMgB,WAAW,MAAM,KAAKC,IAAG;AAC/BC,aAASF,SAAShB,SAAS,GAAG,MAAM,mBAAA;AACpC,UAAMmB,WAAW,MAAMC,QAAQC,WAC7BpB,OAAOqB,QAAQ,MAAM,KAAKC,iBAAgB,GAAIC,UAAU,CAAA,CAAE,GAAGpB,IAAI,OAAOqB,WAAAA;AACtE,YAAMC,eAAqC;QAAEC,QAAQrC;MAA2B;AAChF,YAAMsC,QAAQ,MAAM,KAAKC,UAAUH,cAAcV,QAAAA;AACjD,cAAQ,MAAMS,QAAQG,MAAMA,MAAM,CAAA,GAAIA,MAAM,CAAA,CAAE,KAAK,CAAA;IACrD,CAAA,CAAA,GACCtB,OAAOwB,MAAAA;AAEV,UAAM,KAAKlB,MAAK;AAChB,WAAQO,QAAQb,OAAOyB,SAAAA,EAAW3B,IAAI4B,CAAAA,WAAUA,OAAO3B,KAAK,EAAGC,OAAOwB,MAAAA;EACxE;EAEA,MAAyBG,cAAcC,QAAiC;AACtE,YACE,MAAMd,QAAQH,IACZiB,OAAO9B,IAAI,CAAC+B,SAAAA;AACV,WAAKzC,QAAQ0C,OAAOD,IAAAA;AACpB,aAAOA;IACT,CAAA,CAAA,GAEF7B,OAAOwB,MAAAA;EACX;EAEmBO,WAAWH,QAAiD;AAC7E,UAAMtC,QAAQ,oBAAIC,IAAAA;AAClB,WACEqC,OAAO9B,IAAI,CAAC+B,SAAAA;AACV,aAAO,KAAKzC,QAAQ4C,IAAIH,IAAAA;IAC1B,CAAA,EACA7B,OAAOwB,MAAAA,EACNxB,OAAO,CAACC,YAAAA;AACP,UAAIX,MAAMY,IAAID,QAAQE,KAAK,GAAG;AAC5B,eAAO;MACT,OAAO;AACLb,cAAMc,IAAIH,QAAQE,KAAK;AACvB,eAAO;MACT;IACF,CAAA;EACJ;EAEA,MAAyB8B,cAAcvB,UAAiD;AACtF,UAAMwB,QAAQ,MAAMC,eAAeC,UAAU1B,QAAAA;AAC7C,WAAOwB,MAAMpC,IAAI,CAAC,CAACG,SAAS4B,IAAAA,MAAK;AAC/B,YAAM9B,QAAQsC,KAAKC,UAAUrC,OAAAA;AAC7BW,eAASb,MAAML,SAAS,KAAKhB,cAAc,MAAM,sBAAsBmD,IAAAA,KAAS9B,MAAML,MAAM,GAAG;AAC/F,WAAKN,QAAQmD,IAAIV,MAAM5B,OAAAA;AACvB,WAAKb,QAAQmD,IAAItC,QAAQE,OAAOF,OAAAA;AAChC,aAAOA;IACT,CAAA;EACF;EAEA,MAAyBuC,eAAe;AACtC,UAAM,MAAMA,aAAAA;AACZ,WAAO;EACT;AACF;","names":["assertEx","exists","fulfilled","AbstractArchivist","ArchivistAllQuerySchema","ArchivistClearQuerySchema","ArchivistCommitQuerySchema","ArchivistDeleteQuerySchema","ArchivistInsertQuerySchema","PayloadBuilder","store","storeTypes","store","StorageArchivistConfigSchema","StorageArchivist","AbstractArchivist","configSchemas","defaultConfigSchema","_privateStorage","_storage","maxEntries","config","maxEntrySize","namespace","queries","ArchivistAllQuerySchema","ArchivistDeleteQuerySchema","ArchivistClearQuerySchema","ArchivistInsertQuerySchema","ArchivistCommitQuerySchema","type","privateStorage","storage","allHandler","found","Set","logger","log","length","Object","entries","getAll","map","value","filter","payload","has","$hash","add","clearHandler","clear","emit","mod","commitHandler","payloads","all","assertEx","settled","Promise","allSettled","values","parentArchivists","commit","parent","queryPayload","schema","query","bindQuery","exists","fulfilled","result","deleteHandler","hashes","hash","remove","getHandler","get","insertHandler","pairs","PayloadBuilder","hashPairs","JSON","stringify","set","startHandler"]}
1
+ {"version":3,"sources":["../../src/StorageArchivist.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport { exists } from '@xylabs/exists'\nimport type { Hash } from '@xylabs/hex'\nimport type { Promisable, PromisableArray } from '@xylabs/promise'\nimport { fulfilled } from '@xylabs/promise'\nimport { AbstractArchivist } from '@xyo-network/archivist-abstract'\nimport type {\n ArchivistConfig,\n ArchivistInsertQuery,\n ArchivistInstance,\n ArchivistModuleEventData,\n ArchivistNextOptions,\n ArchivistParams,\n} from '@xyo-network/archivist-model'\nimport {\n ArchivistAllQuerySchema,\n ArchivistClearQuerySchema,\n ArchivistCommitQuerySchema,\n ArchivistDeleteQuerySchema,\n ArchivistInsertQuerySchema,\n} from '@xyo-network/archivist-model'\nimport type { BoundWitness } from '@xyo-network/boundwitness-model'\nimport type { AnyConfigSchema } from '@xyo-network/module-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport type {\n Payload, PayloadWithMeta, Schema, WithMeta,\n} from '@xyo-network/payload-model'\nimport type { StoreBase, StoreType } from 'store2'\nimport store from 'store2'\n\nconst storeTypes = store as unknown as StoreType\n\ntype WithStorageMeta<T extends Payload = Payload> = WithMeta<T> & { _timestamp: number }\n\nexport type StorageArchivistConfigSchema = 'network.xyo.archivist.storage.config'\nexport const StorageArchivistConfigSchema: StorageArchivistConfigSchema = 'network.xyo.archivist.storage.config'\n\nexport type StorageArchivistConfig = ArchivistConfig<{\n maxEntries?: number\n maxEntrySize?: number\n namespace?: string\n schema: StorageArchivistConfigSchema\n type?: 'local' | 'session' | 'page'\n}>\n\nexport type StorageArchivistParams = ArchivistParams<AnyConfigSchema<StorageArchivistConfig>>\nexport class StorageArchivist<\n TParams extends StorageArchivistParams = StorageArchivistParams,\n TEventData extends ArchivistModuleEventData = ArchivistModuleEventData,\n>\n extends AbstractArchivist<TParams, TEventData>\n implements ArchivistInstance {\n static override readonly configSchemas: Schema[] = [...super.configSchemas, StorageArchivistConfigSchema]\n static override readonly defaultConfigSchema: Schema = StorageArchivistConfigSchema\n\n private _privateStorage: StoreBase | undefined\n private _storage: StoreBase | undefined\n\n get maxEntries() {\n return this.config?.maxEntries ?? 1000\n }\n\n get maxEntrySize() {\n return this.config?.maxEntrySize ?? 16_000\n }\n\n get namespace() {\n return this.config?.namespace ?? 'xyo-archivist'\n }\n\n override get queries(): string[] {\n return [\n ArchivistAllQuerySchema,\n ArchivistDeleteQuerySchema,\n ArchivistClearQuerySchema,\n ArchivistInsertQuerySchema,\n ArchivistCommitQuerySchema,\n ...super.queries,\n ]\n }\n\n get type() {\n return this.config?.type ?? 'local'\n }\n\n /* This has to be a getter so that it can access it during construction */\n private get privateStorage(): StoreBase {\n this._privateStorage = this._storage ?? storeTypes[this.type].namespace(`${this.namespace}|private`)\n return this._privateStorage\n }\n\n /* This has to be a getter so that it can access it during construction */\n private get storage(): StoreBase {\n this._storage = this._storage ?? storeTypes[this.type].namespace(this.namespace)\n return this._storage\n }\n\n protected override allHandler(): PromisableArray<PayloadWithMeta> {\n const found = new Set<string>()\n this.logger?.log(`this.storage.length: ${this.storage.length}`)\n return Object.entries(this.storage.getAll())\n .map(([, value]) => value)\n .filter((payload) => {\n if (found.has(payload.$hash)) {\n return false\n } else {\n found.add(payload.$hash)\n return true\n }\n })\n .sort((a, b) => a._timestamp - b._timestamp)\n .map(payload => this.removeStorageMeta(payload))\n }\n\n protected override clearHandler(): void | Promise<void> {\n this.logger?.log(`this.storage.length: ${this.storage.length}`)\n this.storage.clear()\n return this.emit('cleared', { mod: this })\n }\n\n protected override async commitHandler(): Promise<WithMeta<BoundWitness>[]> {\n this.logger?.log(`this.storage.length: ${this.storage.length}`)\n const payloads = await this.all()\n assertEx(payloads.length > 0, () => 'Nothing to commit')\n const settled = (await Promise.allSettled(\n Object.values((await this.parentArchivists()).commit ?? [])?.map(async (parent) => {\n const queryPayload: ArchivistInsertQuery = { schema: ArchivistInsertQuerySchema }\n const query = await this.bindQuery(queryPayload, payloads)\n return (await parent?.query(query[0], query[1]))?.[0]\n }),\n )).filter(exists)\n // TODO - rather than clear, delete the payloads that come back as successfully inserted\n await this.clear()\n return (settled.filter(fulfilled).map(result => result.value)).filter(exists)\n }\n\n protected override async deleteHandler(hashes: Hash[]): Promise<Hash[]> {\n return (\n await Promise.all(\n hashes.map((hash) => {\n this.storage.remove(hash)\n return hash\n }),\n )\n ).filter(exists)\n }\n\n protected getFromOffset(\n order: 'asc' | 'desc' = 'asc',\n limit: number = 10,\n offset?: Hash,\n ): WithStorageMeta[] {\n const offsetHash = offset ? (this.storage.get(offset) as PayloadWithMeta | undefined)?.$hash : undefined\n const found = new Set<string>()\n const payloads: WithStorageMeta[] = Object.entries(this.storage.getAll())\n .map(([, value]) => value)\n .filter((payload) => {\n if (found.has(payload.$hash)) {\n return false\n } else {\n found.add(payload.$hash)\n return true\n }\n })\n .sort((a, b) => {\n return order === 'asc' ? a._timestamp - b._timestamp : b._timestamp - a._timestamp\n })\n if (offsetHash) {\n const index = payloads.findIndex(payload => payload.$hash === offsetHash)\n if (index !== -1) {\n return payloads.slice(index + 1, index + 1 + limit)\n }\n }\n return payloads.slice(0, limit)\n }\n\n protected override getHandler(hashes: string[]): Promisable<PayloadWithMeta[]> {\n const found = new Set<string>()\n return (\n hashes.map((hash) => {\n return this.storage.get(hash)\n })\n ).filter(exists)\n .filter((payload) => {\n if (found.has(payload.$hash)) {\n return false\n } else {\n found.add(payload.$hash)\n return true\n }\n }).map(payload => this.removeStorageMeta(payload))\n }\n\n protected override async insertHandler(payloads: Payload[]): Promise<PayloadWithMeta[]> {\n let timestamp = Date.now()\n const pairs = await PayloadBuilder.hashPairs(payloads)\n return pairs.map(([payload, hash]) => {\n const storagePayload = this.addStorageMeta(payload, timestamp++)\n const value = JSON.stringify(storagePayload)\n console.log('insert.storagePayloads:', storagePayload)\n assertEx(value.length < this.maxEntrySize, () => `Payload too large [${hash}, ${value.length}]`)\n this.storage.set(hash, storagePayload)\n this.storage.set(payload.$hash, storagePayload)\n return payload\n })\n }\n\n protected override nextHandler(options?: ArchivistNextOptions): Promisable<PayloadWithMeta[]> {\n const {\n limit, offset, order,\n } = options ?? {}\n return this.getFromOffset(order, limit ?? 10, offset)\n }\n\n protected override async startHandler() {\n await super.startHandler()\n return true\n }\n\n private addStorageMeta<T extends Payload = Payload>(payload: WithMeta<T>, _timestamp: number): WithStorageMeta<T> {\n return { ...payload, _timestamp }\n }\n\n private removeStorageMeta<T extends Payload = Payload>(payload: WithStorageMeta<T>): WithMeta<T> {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { _timestamp, ...rest } = payload\n return rest as WithMeta<T>\n }\n}\n"],"mappings":"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","names":["assertEx","exists","fulfilled","AbstractArchivist","ArchivistAllQuerySchema","ArchivistClearQuerySchema","ArchivistCommitQuerySchema","ArchivistDeleteQuerySchema","ArchivistInsertQuerySchema","PayloadBuilder","store","storeTypes","store","StorageArchivistConfigSchema","StorageArchivist","AbstractArchivist","configSchemas","defaultConfigSchema","_privateStorage","_storage","maxEntries","config","maxEntrySize","namespace","queries","ArchivistAllQuerySchema","ArchivistDeleteQuerySchema","ArchivistClearQuerySchema","ArchivistInsertQuerySchema","ArchivistCommitQuerySchema","type","privateStorage","storage","allHandler","found","Set","logger","log","length","Object","entries","getAll","map","value","filter","payload","has","$hash","add","sort","a","b","_timestamp","removeStorageMeta","clearHandler","clear","emit","mod","commitHandler","payloads","all","assertEx","settled","Promise","allSettled","values","parentArchivists","commit","parent","queryPayload","schema","query","bindQuery","exists","fulfilled","result","deleteHandler","hashes","hash","remove","getFromOffset","order","limit","offset","offsetHash","get","undefined","index","findIndex","slice","getHandler","insertHandler","timestamp","Date","now","pairs","PayloadBuilder","hashPairs","storagePayload","addStorageMeta","JSON","stringify","console","set","nextHandler","options","startHandler","rest"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/archivist-storage",
3
- "version": "3.3.1",
3
+ "version": "3.3.3",
4
4
  "description": "Primary SDK for using XYO Protocol 2.0",
5
5
  "homepage": "https://xyo.network",
6
6
  "bugs": {
@@ -29,29 +29,31 @@
29
29
  "module": "dist/neutral/index.mjs",
30
30
  "types": "dist/neutral/index.d.ts",
31
31
  "dependencies": {
32
- "@xylabs/assert": "^4.3.2",
33
- "@xylabs/exists": "^4.3.2",
34
- "@xylabs/hex": "^4.3.2",
35
- "@xylabs/promise": "^4.3.2",
36
- "@xyo-network/archivist-abstract": "^3.3.1",
37
- "@xyo-network/archivist-model": "^3.3.1",
38
- "@xyo-network/boundwitness-model": "^3.3.1",
39
- "@xyo-network/module-model": "^3.3.1",
40
- "@xyo-network/payload-builder": "^3.3.1",
41
- "@xyo-network/payload-model": "^3.3.1",
32
+ "@xylabs/assert": "^4.3.4",
33
+ "@xylabs/exists": "^4.3.4",
34
+ "@xylabs/hex": "^4.3.4",
35
+ "@xylabs/promise": "^4.3.4",
36
+ "@xyo-network/archivist-abstract": "^3.3.3",
37
+ "@xyo-network/archivist-model": "^3.3.3",
38
+ "@xyo-network/boundwitness-model": "^3.3.3",
39
+ "@xyo-network/module-model": "^3.3.3",
40
+ "@xyo-network/payload-builder": "^3.3.3",
41
+ "@xyo-network/payload-model": "^3.3.3",
42
42
  "store2": "^2.14.3"
43
43
  },
44
44
  "devDependencies": {
45
- "@xylabs/delay": "^4.3.2",
45
+ "@xylabs/delay": "^4.3.4",
46
+ "@xylabs/object": "^4.3.4",
46
47
  "@xylabs/ts-scripts-yarn3": "^4.2.3",
47
48
  "@xylabs/tsconfig": "^4.2.3",
48
- "@xyo-network/account": "^3.3.1",
49
- "@xyo-network/archivist-memory": "^3.3.1",
50
- "@xyo-network/boundwitness-wrapper": "^3.3.1",
51
- "@xyo-network/id-payload-plugin": "^3.3.1",
52
- "@xyo-network/node-memory": "^3.3.1",
53
- "@xyo-network/payload-wrapper": "^3.3.1",
54
- "typescript": "^5.6.3"
49
+ "@xyo-network/account": "^3.3.3",
50
+ "@xyo-network/archivist-memory": "^3.3.3",
51
+ "@xyo-network/boundwitness-wrapper": "^3.3.3",
52
+ "@xyo-network/id-payload-plugin": "^3.3.3",
53
+ "@xyo-network/node-memory": "^3.3.3",
54
+ "@xyo-network/payload-wrapper": "^3.3.3",
55
+ "typescript": "^5.6.3",
56
+ "vitest": "^2.1.4"
55
57
  },
56
58
  "publishConfig": {
57
59
  "access": "public"
@@ -9,6 +9,7 @@ import type {
9
9
  ArchivistInsertQuery,
10
10
  ArchivistInstance,
11
11
  ArchivistModuleEventData,
12
+ ArchivistNextOptions,
12
13
  ArchivistParams,
13
14
  } from '@xyo-network/archivist-model'
14
15
  import {
@@ -29,6 +30,8 @@ import store from 'store2'
29
30
 
30
31
  const storeTypes = store as unknown as StoreType
31
32
 
33
+ type WithStorageMeta<T extends Payload = Payload> = WithMeta<T> & { _timestamp: number }
34
+
32
35
  export type StorageArchivistConfigSchema = 'network.xyo.archivist.storage.config'
33
36
  export const StorageArchivistConfigSchema: StorageArchivistConfigSchema = 'network.xyo.archivist.storage.config'
34
37
 
@@ -92,24 +95,6 @@ export class StorageArchivist<
92
95
  return this._storage
93
96
  }
94
97
 
95
- /* override async loadAccount(account?: AccountInstance, persistAccount?: boolean, privateStorage?: StoreBase, _logger?: Logger) {
96
- if (!this._account) {
97
- if (persistAccount) {
98
- const privateKey = privateStorage?.get('privateKey')
99
- if (privateKey) {
100
- try {
101
- this._account = await Account.create({ privateKey })
102
- return this._account
103
- } catch (ex) {
104
- console.error(`Error reading Account from storage [${ex}] - Recreating Account`)
105
- privateStorage?.remove('privateKey')
106
- }
107
- }
108
- }
109
- }
110
- return await super.loadAccount()
111
- } */
112
-
113
98
  protected override allHandler(): PromisableArray<PayloadWithMeta> {
114
99
  const found = new Set<string>()
115
100
  this.logger?.log(`this.storage.length: ${this.storage.length}`)
@@ -123,6 +108,8 @@ export class StorageArchivist<
123
108
  return true
124
109
  }
125
110
  })
111
+ .sort((a, b) => a._timestamp - b._timestamp)
112
+ .map(payload => this.removeStorageMeta(payload))
126
113
  }
127
114
 
128
115
  protected override clearHandler(): void | Promise<void> {
@@ -158,6 +145,35 @@ export class StorageArchivist<
158
145
  ).filter(exists)
159
146
  }
160
147
 
148
+ protected getFromOffset(
149
+ order: 'asc' | 'desc' = 'asc',
150
+ limit: number = 10,
151
+ offset?: Hash,
152
+ ): WithStorageMeta[] {
153
+ const offsetHash = offset ? (this.storage.get(offset) as PayloadWithMeta | undefined)?.$hash : undefined
154
+ const found = new Set<string>()
155
+ const payloads: WithStorageMeta[] = Object.entries(this.storage.getAll())
156
+ .map(([, value]) => value)
157
+ .filter((payload) => {
158
+ if (found.has(payload.$hash)) {
159
+ return false
160
+ } else {
161
+ found.add(payload.$hash)
162
+ return true
163
+ }
164
+ })
165
+ .sort((a, b) => {
166
+ return order === 'asc' ? a._timestamp - b._timestamp : b._timestamp - a._timestamp
167
+ })
168
+ if (offsetHash) {
169
+ const index = payloads.findIndex(payload => payload.$hash === offsetHash)
170
+ if (index !== -1) {
171
+ return payloads.slice(index + 1, index + 1 + limit)
172
+ }
173
+ }
174
+ return payloads.slice(0, limit)
175
+ }
176
+
161
177
  protected override getHandler(hashes: string[]): Promisable<PayloadWithMeta[]> {
162
178
  const found = new Set<string>()
163
179
  return (
@@ -172,22 +188,42 @@ export class StorageArchivist<
172
188
  found.add(payload.$hash)
173
189
  return true
174
190
  }
175
- })
191
+ }).map(payload => this.removeStorageMeta(payload))
176
192
  }
177
193
 
178
194
  protected override async insertHandler(payloads: Payload[]): Promise<PayloadWithMeta[]> {
195
+ let timestamp = Date.now()
179
196
  const pairs = await PayloadBuilder.hashPairs(payloads)
180
197
  return pairs.map(([payload, hash]) => {
181
- const value = JSON.stringify(payload)
198
+ const storagePayload = this.addStorageMeta(payload, timestamp++)
199
+ const value = JSON.stringify(storagePayload)
200
+ console.log('insert.storagePayloads:', storagePayload)
182
201
  assertEx(value.length < this.maxEntrySize, () => `Payload too large [${hash}, ${value.length}]`)
183
- this.storage.set(hash, payload)
184
- this.storage.set(payload.$hash, payload)
202
+ this.storage.set(hash, storagePayload)
203
+ this.storage.set(payload.$hash, storagePayload)
185
204
  return payload
186
205
  })
187
206
  }
188
207
 
208
+ protected override nextHandler(options?: ArchivistNextOptions): Promisable<PayloadWithMeta[]> {
209
+ const {
210
+ limit, offset, order,
211
+ } = options ?? {}
212
+ return this.getFromOffset(order, limit ?? 10, offset)
213
+ }
214
+
189
215
  protected override async startHandler() {
190
216
  await super.startHandler()
191
217
  return true
192
218
  }
219
+
220
+ private addStorageMeta<T extends Payload = Payload>(payload: WithMeta<T>, _timestamp: number): WithStorageMeta<T> {
221
+ return { ...payload, _timestamp }
222
+ }
223
+
224
+ private removeStorageMeta<T extends Payload = Payload>(payload: WithStorageMeta<T>): WithMeta<T> {
225
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
226
+ const { _timestamp, ...rest } = payload
227
+ return rest as WithMeta<T>
228
+ }
193
229
  }