@ariestools/aries-dapp-core 0.1.16 → 0.1.17
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/bin/dappServer.mjs +55 -56
- package/dist/node/DappActor.d.ts +12 -4
- package/dist/node/DappActor.d.ts.map +1 -1
- package/dist/node/actor/types.d.ts +3 -1
- package/dist/node/actor/types.d.ts.map +1 -1
- package/dist/node/bin/loadReducer.d.ts +3 -1
- package/dist/node/bin/loadReducer.d.ts.map +1 -1
- package/dist/node/consumer.mjs.map +2 -2
- package/dist/node/index.mjs +9 -3
- package/dist/node/index.mjs.map +2 -2
- package/dist/node/providers/DappBucketStore.d.ts +3 -1
- package/dist/node/providers/DappBucketStore.d.ts.map +1 -1
- package/dist/node/providers/capabilities.d.ts +3 -1
- package/dist/node/providers/capabilities.d.ts.map +1 -1
- package/dist/node/providers/hashBytes.d.ts +3 -1
- package/dist/node/providers/hashBytes.d.ts.map +1 -1
- package/dist/node/providers/joinKey.d.ts +6 -2
- package/dist/node/providers/joinKey.d.ts.map +1 -1
- package/dist/node/providers/types.d.ts +21 -7
- package/dist/node/providers/types.d.ts.map +1 -1
- package/dist/node/publication/constants.d.ts +24 -8
- package/dist/node/publication/constants.d.ts.map +1 -1
- package/dist/node/publication/gc.d.ts +6 -2
- package/dist/node/publication/gc.d.ts.map +1 -1
- package/dist/node/publication/incremental.d.ts +9 -3
- package/dist/node/publication/incremental.d.ts.map +1 -1
- package/dist/node/publication/releases.d.ts +12 -4
- package/dist/node/publication/releases.d.ts.map +1 -1
- package/dist/node/publication/status.d.ts +3 -1
- package/dist/node/publication/status.d.ts.map +1 -1
- package/dist/node/publication/statusPatch.d.ts +9 -3
- package/dist/node/publication/statusPatch.d.ts.map +1 -1
- package/dist/node/publication/types.d.ts +42 -14
- package/dist/node/publication/types.d.ts.map +1 -1
- package/dist/node/reducer/DappReducer.d.ts +9 -3
- package/dist/node/reducer/DappReducer.d.ts.map +1 -1
- package/examples/countFactsReducer.mjs +3 -1
- package/package.json +17 -13
package/dist/bin/dappServer.mjs
CHANGED
|
@@ -3,13 +3,17 @@ import { createRequire } from "node:module";
|
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
|
+
import { runActorsService } from "@ariestools/actor-cli";
|
|
6
7
|
import { DAPP_BACKINGS, DAPP_BUCKETS, isDappBackingKind, resolveBacking, startDappServer } from "@ariestools/aries-dapp-serve";
|
|
8
|
+
import { createNodeProcessHost } from "@ariestools/cli-kit-node";
|
|
7
9
|
import { ConsoleLogger, assertEx, creatable } from "@ariestools/sdk";
|
|
8
|
-
import { PeriodicActor
|
|
10
|
+
import { PeriodicActor } from "@ariestools/actor";
|
|
9
11
|
import { DeleteObjectCommand, GetObjectCommand, HeadObjectCommand, ListObjectsV2Command, PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
|
10
12
|
import { pathToFileURL } from "node:url";
|
|
11
13
|
//#region src/providers/capabilities.ts
|
|
12
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
Thrown when a read-only capability wrapper receives a write.
|
|
16
|
+
*/
|
|
13
17
|
var ReadOnlyStoreError = class extends Error {
|
|
14
18
|
name = "ReadOnlyStoreError";
|
|
15
19
|
constructor(role, operation = "put") {
|
|
@@ -66,10 +70,14 @@ const DappStateStoreMoniker = "DappStateStore";
|
|
|
66
70
|
const DappIndexStoreMoniker = "DappIndexStore";
|
|
67
71
|
//#endregion
|
|
68
72
|
//#region src/publication/constants.ts
|
|
69
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
Well-known relative keys published by the coherent generation protocol.
|
|
75
|
+
*/
|
|
70
76
|
const HEAD_KEY = "head.json";
|
|
71
77
|
const STATUS_KEY = "status.json";
|
|
72
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
CDN caching: mutable head and status objects that must revalidate.
|
|
80
|
+
*/
|
|
73
81
|
const CACHE_CONTROL_REVALIDATE = "public, max-age=0, must-revalidate";
|
|
74
82
|
const INDEXER_STATUS_SCHEMA = "network.aries.dapp.indexer.status";
|
|
75
83
|
//#endregion
|
|
@@ -134,7 +142,9 @@ const PROGRESS_KEYS = [
|
|
|
134
142
|
"generation",
|
|
135
143
|
"generationRoot"
|
|
136
144
|
];
|
|
137
|
-
/**
|
|
145
|
+
/**
|
|
146
|
+
Carry forward durable progress fields from a prior status object.
|
|
147
|
+
*/
|
|
138
148
|
function priorProgressFields(prior) {
|
|
139
149
|
if (prior === void 0) return {};
|
|
140
150
|
return {
|
|
@@ -142,7 +152,9 @@ function priorProgressFields(prior) {
|
|
|
142
152
|
...prior.lastSuccessAt !== void 0 && { lastSuccessAt: prior.lastSuccessAt }
|
|
143
153
|
};
|
|
144
154
|
}
|
|
145
|
-
/**
|
|
155
|
+
/**
|
|
156
|
+
Build success status fields from reduce progress, falling back to prior.
|
|
157
|
+
*/
|
|
146
158
|
function successStatusFields(progress, prior, now) {
|
|
147
159
|
const fromProgress = progress === void 0 ? {} : pickDefined(progress, PROGRESS_KEYS);
|
|
148
160
|
const generation = progress?.generation ?? prior?.generation;
|
|
@@ -157,7 +169,9 @@ function successStatusFields(progress, prior, now) {
|
|
|
157
169
|
...prior?.lastErrorAt !== void 0 && { lastErrorAt: prior.lastErrorAt }
|
|
158
170
|
};
|
|
159
171
|
}
|
|
160
|
-
/**
|
|
172
|
+
/**
|
|
173
|
+
Build failure status fields while preserving prior checkpoint progress.
|
|
174
|
+
*/
|
|
161
175
|
function failureStatusFields(prior, consecutiveFailures, error, now) {
|
|
162
176
|
return {
|
|
163
177
|
consecutiveFailures,
|
|
@@ -167,7 +181,7 @@ function failureStatusFields(prior, consecutiveFailures, error, now) {
|
|
|
167
181
|
};
|
|
168
182
|
}
|
|
169
183
|
//#endregion
|
|
170
|
-
//#region \0@oxc-project+runtime@0.
|
|
184
|
+
//#region \0@oxc-project+runtime@0.143.0/helpers/esm/decorate.js
|
|
171
185
|
function __decorate(decorators, target, key, desc) {
|
|
172
186
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
173
187
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -194,11 +208,15 @@ let DappActor = class DappActor extends PeriodicActor {
|
|
|
194
208
|
_data;
|
|
195
209
|
_index;
|
|
196
210
|
_state;
|
|
197
|
-
/**
|
|
211
|
+
/**
|
|
212
|
+
Dapp actors require a logger in the locator context (see {@link DappContext}).
|
|
213
|
+
*/
|
|
198
214
|
get logger() {
|
|
199
215
|
return assertEx(super.logger, () => `Logger is required in context for actor ${this.name}.`);
|
|
200
216
|
}
|
|
201
|
-
/**
|
|
217
|
+
/**
|
|
218
|
+
Reduce cadence: `reduceIntervalMs` names the interval in dapp configs.
|
|
219
|
+
*/
|
|
202
220
|
get intervalMs() {
|
|
203
221
|
return this.params.reduceIntervalMs ?? DEFAULT_REDUCE_INTERVAL_MS;
|
|
204
222
|
}
|
|
@@ -213,7 +231,9 @@ let DappActor = class DappActor extends PeriodicActor {
|
|
|
213
231
|
await super.startHandler();
|
|
214
232
|
this.logger.info(`DappActor started: reducer '${this.params.reducer.name}' every ${this.intervalMs}ms (first run in ${this.firstRunDelayMs}ms)`);
|
|
215
233
|
}
|
|
216
|
-
/**
|
|
234
|
+
/**
|
|
235
|
+
Failure side-channel: publish durable failure status (count already incremented).
|
|
236
|
+
*/
|
|
217
237
|
async onPassError(error) {
|
|
218
238
|
await this.safePublishStatus(void 0, error);
|
|
219
239
|
}
|
|
@@ -251,33 +271,6 @@ let DappActor = class DappActor extends PeriodicActor {
|
|
|
251
271
|
};
|
|
252
272
|
DappActor = __decorate([creatable()], DappActor);
|
|
253
273
|
//#endregion
|
|
254
|
-
//#region src/boot/bootDappActors.ts
|
|
255
|
-
/**
|
|
256
|
-
* Creates and starts one {@link DappActor} per spec, all sharing the single
|
|
257
|
-
* process-wide locator. A thin wrapper over actor-kit's `bootActors`: on
|
|
258
|
-
* partial failure, actors already started are stopped (with shutdown
|
|
259
|
-
* fallback) before the error is rethrown. Returns them so the caller can
|
|
260
|
-
* stop them on shutdown.
|
|
261
|
-
*/
|
|
262
|
-
async function bootDappActors(locator, specs) {
|
|
263
|
-
return await bootActors(specs.map((spec) => {
|
|
264
|
-
const params = {
|
|
265
|
-
locator,
|
|
266
|
-
name: spec.name,
|
|
267
|
-
reducer: spec.reducer,
|
|
268
|
-
...spec.reduceIntervalMs !== void 0 && { reduceIntervalMs: spec.reduceIntervalMs },
|
|
269
|
-
...spec.firstRunDelayMs !== void 0 && { firstRunDelayMs: spec.firstRunDelayMs },
|
|
270
|
-
...spec.maxConsecutiveFailures !== void 0 && { maxConsecutiveFailures: spec.maxConsecutiveFailures },
|
|
271
|
-
...spec.publishStatus !== void 0 && { publishStatus: spec.publishStatus },
|
|
272
|
-
...spec.shutdownTimeoutMs !== void 0 && { shutdownTimeoutMs: spec.shutdownTimeoutMs }
|
|
273
|
-
};
|
|
274
|
-
return {
|
|
275
|
-
create: () => DappActor.create(params),
|
|
276
|
-
...spec.runReady !== void 0 && { runReady: spec.runReady }
|
|
277
|
-
};
|
|
278
|
-
}));
|
|
279
|
-
}
|
|
280
|
-
//#endregion
|
|
281
274
|
//#region src/providers/errors.ts
|
|
282
275
|
/**
|
|
283
276
|
* Thrown when a conditional put fails (object already exists under
|
|
@@ -305,7 +298,9 @@ function joinKey(prefix, relativeKey) {
|
|
|
305
298
|
if (cleanKey.length === 0) return cleanPrefix;
|
|
306
299
|
return `${cleanPrefix}/${cleanKey}`;
|
|
307
300
|
}
|
|
308
|
-
/**
|
|
301
|
+
/**
|
|
302
|
+
Strip a role prefix from a physical key, returning the relative key.
|
|
303
|
+
*/
|
|
309
304
|
function stripPrefix(prefix, physicalKey) {
|
|
310
305
|
const cleanPrefix = prefix.replaceAll(/^\/+|\/+$/g, "");
|
|
311
306
|
if (cleanPrefix.length === 0) return physicalKey;
|
|
@@ -314,7 +309,9 @@ function stripPrefix(prefix, physicalKey) {
|
|
|
314
309
|
if (physicalKey.startsWith(withSlash)) return physicalKey.slice(withSlash.length);
|
|
315
310
|
return physicalKey;
|
|
316
311
|
}
|
|
317
|
-
/**
|
|
312
|
+
/**
|
|
313
|
+
Normalize an optional public base URL (no trailing slash).
|
|
314
|
+
*/
|
|
318
315
|
function normalizePublicBaseUrl(url) {
|
|
319
316
|
if (url === void 0 || url.length === 0) return void 0;
|
|
320
317
|
return url.replace(/\/+$/, "");
|
|
@@ -730,28 +727,30 @@ async function main() {
|
|
|
730
727
|
});
|
|
731
728
|
process.env.DAPP_PUBLICATION_SAFETY ??= "unfenced";
|
|
732
729
|
process.env.DAPP_ENDPOINT ??= server.baseUrl;
|
|
733
|
-
const actors = await
|
|
730
|
+
const actors = [await DappActor.create({
|
|
731
|
+
firstRunDelayMs: FIRST_RUN_DELAY_MS,
|
|
732
|
+
locator,
|
|
734
733
|
name: "DappActor",
|
|
735
|
-
reducer,
|
|
734
|
+
publishStatus: reducer.name !== "noop",
|
|
736
735
|
reduceIntervalMs: REDUCE_INTERVAL_MS,
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
}]);
|
|
736
|
+
reducer
|
|
737
|
+
})];
|
|
740
738
|
const versionSuffix = reducer.version === void 0 ? "" : `@${reducer.version}`;
|
|
741
739
|
const reducerLine = REDUCER_SPEC === void 0 ? "\nreducer: noop (pass DAPP_REDUCER / --reducer for real logic)" : `\nreducer: ${REDUCER_SPEC}`;
|
|
742
|
-
|
|
743
|
-
const
|
|
744
|
-
|
|
740
|
+
const banner = `[dev-only] dapp server listening at ${server.baseUrl}\n` + DAPP_BUCKETS.map((bucket) => ` /${bucket.padEnd(5)} ${server.baseUrl}/${bucket}`).join("\n") + `\nbacking: ${backing.description}\nactors: ${actors.length} (reducer '${reducer.name}'${versionSuffix}, every ${REDUCE_INTERVAL_MS}ms)` + reducerLine;
|
|
741
|
+
const processHost = createNodeProcessHost({ signals: ["SIGINT", "SIGTERM"] });
|
|
742
|
+
try {
|
|
743
|
+
await runActorsService(processHost, {
|
|
744
|
+
actors,
|
|
745
|
+
onReady: () => {
|
|
746
|
+
console.log(banner);
|
|
747
|
+
},
|
|
748
|
+
supervisor: "parallel"
|
|
749
|
+
});
|
|
750
|
+
} finally {
|
|
745
751
|
locator.destroy();
|
|
746
752
|
await server.close();
|
|
747
|
-
|
|
748
|
-
};
|
|
749
|
-
process.on("SIGINT", () => {
|
|
750
|
-
shutdown();
|
|
751
|
-
});
|
|
752
|
-
process.on("SIGTERM", () => {
|
|
753
|
-
shutdown();
|
|
754
|
-
});
|
|
753
|
+
}
|
|
755
754
|
}
|
|
756
755
|
main().catch((error) => {
|
|
757
756
|
console.error(error);
|
package/dist/node/DappActor.d.ts
CHANGED
|
@@ -10,7 +10,9 @@ export interface DappActorParams extends PeriodicActorParams<DappProviderLocator
|
|
|
10
10
|
* after each reduce pass (success or failure).
|
|
11
11
|
*/
|
|
12
12
|
publishStatus?: boolean;
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
Period between reduce passes. Defaults to 5000ms.
|
|
15
|
+
*/
|
|
14
16
|
reduceIntervalMs?: number;
|
|
15
17
|
reducer: DappReducer;
|
|
16
18
|
}
|
|
@@ -28,13 +30,19 @@ export declare class DappActor extends PeriodicActor<DappActorParams> {
|
|
|
28
30
|
protected _data: DappObjectReader;
|
|
29
31
|
protected _index: DappObjectWriter;
|
|
30
32
|
protected _state: DappObjectWriter;
|
|
31
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
Dapp actors require a logger in the locator context (see {@link DappContext}).
|
|
35
|
+
*/
|
|
32
36
|
get logger(): Logger;
|
|
33
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
Reduce cadence: `reduceIntervalMs` names the interval in dapp configs.
|
|
39
|
+
*/
|
|
34
40
|
protected get intervalMs(): number;
|
|
35
41
|
createHandler(): Promise<void>;
|
|
36
42
|
startHandler(): Promise<void>;
|
|
37
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
Failure side-channel: publish durable failure status (count already incremented).
|
|
45
|
+
*/
|
|
38
46
|
protected onPassError(error: Error): Promise<void>;
|
|
39
47
|
protected runPass({ signal }: PeriodicPassContext): Promise<void>;
|
|
40
48
|
private publishStatusFromProgress;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DappActor.d.ts","sourceRoot":"","sources":["../../src/DappActor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAG7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AASrF,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAE/E,MAAM,WAAW,eAAgB,SAAQ,mBAAmB,CAAC,mBAAmB,CAAC;IAC/E;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB
|
|
1
|
+
{"version":3,"file":"DappActor.d.ts","sourceRoot":"","sources":["../../src/DappActor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAG7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AASrF,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAE/E,MAAM,WAAW,eAAgB,SAAQ,mBAAmB,CAAC,mBAAmB,CAAC;IAC/E;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;MAEE;IACF,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,OAAO,EAAE,WAAW,CAAA;CACrB;AAYD;;;;;;;;GAQG;AACH,qBACa,SAAU,SAAQ,aAAa,CAAC,eAAe,CAAC;IAC3D,MAAM,CAAC,QAAQ,CAAC,YAAY,iEAIlB;IAEV,SAAS,CAAC,KAAK,EAAG,gBAAgB,CAAA;IAClC,SAAS,CAAC,MAAM,EAAG,gBAAgB,CAAA;IACnC,SAAS,CAAC,MAAM,EAAG,gBAAgB,CAAA;IAEnC;;MAEE;IACF,IAAa,MAAM,IAAI,MAAM,CAE5B;IAED;;MAEE;IACF,cAAuB,UAAU,IAAI,MAAM,CAE1C;IAEc,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAS9B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5C;;MAEE;cACuB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;cAIxC,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;YAclE,yBAAyB;YAkBzB,iBAAiB;CAUhC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ActorContext, InstanceLocator, OwnedLocator, RegistrableLocator } from '@ariestools/actor-model';
|
|
2
2
|
import type { Logger } from '@ariestools/sdk';
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
Identifier a provider is registered and resolved under in the locator.
|
|
5
|
+
*/
|
|
4
6
|
export type DappMoniker = string;
|
|
5
7
|
/**
|
|
6
8
|
* The shared context carried by the process-wide locator. A `logger` is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/actor/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,kBAAkB,EACnB,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE7C
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/actor/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,kBAAkB,EACnB,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE7C;;EAEE;AACF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAA;AAEhC;;;;GAIG;AACH,MAAM,WAAW,WAAY,SAAQ,YAAY;IAC/C,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,eAAe,CAAC,WAAW,CAAC,GAAG,YAAY,GAAG,kBAAkB,GAAG;IACnG,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAA;CACnC,CAAA"}
|
|
@@ -5,7 +5,9 @@ export interface LoadReducerOptions {
|
|
|
5
5
|
* Defaults to trying `reducer`, then `default`.
|
|
6
6
|
*/
|
|
7
7
|
exportName?: string;
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
Absolute or relative path to a `.mjs` file, or a resolvable package export.
|
|
10
|
+
*/
|
|
9
11
|
spec: string;
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadReducer.d.ts","sourceRoot":"","sources":["../../../src/bin/loadReducer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAI5D,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB
|
|
1
|
+
{"version":3,"file":"loadReducer.d.ts","sourceRoot":"","sources":["../../../src/bin/loadReducer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAI5D,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;MAEE;IACF,IAAI,EAAE,MAAM,CAAA;CACb;AA6DD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAOnF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/publication/canonicalHead.ts", "../../src/publication/constants.ts", "../../src/publication/shard.ts", "../../src/consumer/hash.ts", "../../src/consumer/parse.ts", "../../src/consumer/api.ts"],
|
|
4
|
-
"sourcesContent": ["import type { HeadManifest } from './types.ts'\n\n/**\n * Canonical UTF-8 JSON bytes for head signing/verification. Excludes\n * `signature` and uses a fixed field order so Node and browser agree.\n */\nexport function canonicalHeadBytes(head: HeadManifest): Uint8Array {\n const payload: Record<string, unknown> = {\n schema: head.schema,\n generation: head.generation,\n manifestKey: head.manifestKey,\n manifestHash: head.manifestHash,\n publishedAt: head.publishedAt,\n }\n if (head.previousGeneration !== undefined) {\n payload.previousGeneration = head.previousGeneration\n }\n if (head.revision !== undefined) payload.revision = head.revision\n if (head.trust !== undefined) payload.trust = head.trust\n if (head.layout !== undefined) payload.layout = head.layout\n // Stable key order via explicit construction above (not Object key enum order).\n const ordered: Record<string, unknown> = {}\n for (const key of [\n 'schema',\n 'generation',\n 'manifestKey',\n 'manifestHash',\n 'publishedAt',\n 'previousGeneration',\n 'revision',\n 'trust',\n 'layout',\n ]) {\n if (key in payload) ordered[key] = payload[key]\n }\n return new TextEncoder().encode(`${JSON.stringify(ordered)}\\n`)\n}\n", "/** Well-known relative keys published by the coherent generation protocol. */\nexport const HEAD_KEY = 'head.json'\nexport const STATUS_KEY = 'status.json'\nexport const PINS_KEY = 'pins.json'\nexport const GENERATIONS_PREFIX = 'generations'\n/** Content-addressed object bodies (incremental layout). */\nexport const CAS_PREFIX = 'cas/sha256'\n/** Sharded logical map roots (incremental layout). */\nexport const MAP_ROOTS_PREFIX = 'map/roots'\n/** Sharded logical map shards (incremental layout). */\nexport const MAP_SHARDS_PREFIX = 'map/shards'\n/** Small generation receipts for incremental layout. */\nexport const RECEIPTS_PREFIX = 'receipts'\n\n/** CDN caching: immutable generation objects and manifests. */\nexport const CACHE_CONTROL_IMMUTABLE = 'public, max-age=31536000, immutable'\n/** CDN caching: mutable head and status objects that must revalidate. */\nexport const CACHE_CONTROL_REVALIDATE = 'public, max-age=0, must-revalidate'\n\nexport const GENERATION_MANIFEST_SCHEMA = 'network.aries.dapp.generation.manifest' as const\nexport const HEAD_MANIFEST_SCHEMA = 'network.aries.dapp.head' as const\nexport const INDEXER_STATUS_SCHEMA = 'network.aries.dapp.indexer.status' as const\nexport const PINS_SCHEMA = 'network.aries.dapp.pins' as const\nexport const MAP_ROOT_SCHEMA = 'network.aries.dapp.map.root' as const\nexport const MAP_SHARD_SCHEMA = 'network.aries.dapp.map.shard' as const\nexport const RECEIPT_SCHEMA = 'network.aries.dapp.generation.receipt' as const\n\n/** Default shard width: first 2 hex chars of sha256(logicalKey) \u2192 256 shards. */\nexport const DEFAULT_SHARD_HEX_CHARS = 2\n", "import { DEFAULT_SHARD_HEX_CHARS } from './constants.ts'\n\n/**\n * Shard routing id for a logical key. FNV-1a 32-bit, hex-padded \u2014 used only to\n * partition the logical map (not for content integrity). Must match between\n * writer and browser consumer (no crypto required).\n */\nexport function shardIdForKey(logicalKey: string, hexChars = DEFAULT_SHARD_HEX_CHARS): string {\n let h = 0x81_1C_9D_C5\n for (let i = 0; i < logicalKey.length; i++) {\n h ^= logicalKey.codePointAt(i)!\n h = Math.imul(h, 0x01_00_01_93)\n }\n return (h >>> 0).toString(16).padStart(8, '0').slice(0, hexChars)\n}\n", "/**\n * Browser-neutral SHA-256 via Web Crypto (`crypto.subtle`).\n * Available in modern browsers and Node \u226518 without Node crypto modules.\n */\n\nfunction bytesOf(body: string | Uint8Array): Uint8Array {\n return typeof body === 'string' ? new TextEncoder().encode(body) : body\n}\n\nfunction toHex(bytes: Uint8Array): string {\n let out = ''\n for (const b of bytes) out += b.toString(16).padStart(2, '0')\n return out\n}\n\nfunction requireSubtle(): SubtleCrypto {\n const subtle = globalThis.crypto?.subtle\n if (subtle === undefined) {\n throw new Error('Web Crypto subtle API is required for consumer hashing')\n }\n return subtle\n}\n\nexport async function hashBytesAsync(body: string | Uint8Array): Promise<string> {\n const data = bytesOf(body)\n const digest = await requireSubtle().digest(\n 'SHA-256',\n data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) as ArrayBuffer,\n )\n return toHex(new Uint8Array(digest))\n}\n", "import {\n GENERATION_MANIFEST_SCHEMA,\n HEAD_MANIFEST_SCHEMA,\n INDEXER_STATUS_SCHEMA,\n MAP_ROOT_SCHEMA,\n MAP_SHARD_SCHEMA,\n} from '../publication/constants.ts'\nimport type {\n GenerationManifest, HeadManifest, IndexerStatus,\n} from '../publication/types.ts'\n\nfunction asRecord(value: unknown, label: string): Record<string, unknown> {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`Invalid ${label}: expected object`)\n }\n return value as Record<string, unknown>\n}\n\nfunction requireString(obj: Record<string, unknown>, key: string, label: string): string {\n const v = obj[key]\n if (typeof v !== 'string' || v.length === 0) {\n throw new Error(`Invalid ${label}: missing string \"${key}\"`)\n }\n return v\n}\n\nexport function parseHead(json: unknown): HeadManifest {\n const obj = asRecord(json, 'head')\n if (obj.schema !== HEAD_MANIFEST_SCHEMA) {\n throw new Error(`Invalid head schema: ${String(obj.schema)}`)\n }\n return {\n schema: HEAD_MANIFEST_SCHEMA,\n generation: requireString(obj, 'generation', 'head'),\n manifestKey: requireString(obj, 'manifestKey', 'head'),\n manifestHash: requireString(obj, 'manifestHash', 'head'),\n publishedAt: requireString(obj, 'publishedAt', 'head'),\n ...(typeof obj.previousGeneration === 'string'\n && { previousGeneration: obj.previousGeneration }),\n ...(typeof obj.revision === 'number' && { revision: obj.revision }),\n ...(obj.trust === 'trusted-origin' || obj.trust === 'signed'\n ? { trust: obj.trust }\n : {}),\n ...(typeof obj.signature === 'string' && { signature: obj.signature }),\n ...(obj.layout === 'full' || obj.layout === 'incremental-cas'\n ? { layout: obj.layout }\n : {}),\n }\n}\n\nexport function parseGenerationManifest(json: unknown): GenerationManifest {\n const obj = asRecord(json, 'manifest')\n if (obj.schema !== GENERATION_MANIFEST_SCHEMA) {\n throw new Error(`Invalid generation manifest schema: ${String(obj.schema)}`)\n }\n if (!Array.isArray(obj.objects)) {\n throw new TypeError('Invalid generation manifest: objects must be an array')\n }\n return obj as unknown as GenerationManifest\n}\n\nexport function parseIndexerStatus(json: unknown): IndexerStatus {\n const obj = asRecord(json, 'status')\n if (obj.schema !== INDEXER_STATUS_SCHEMA) {\n throw new Error(`Invalid status schema: ${String(obj.schema)}`)\n }\n return obj as unknown as IndexerStatus\n}\n\nexport function parseMapRoot(json: unknown): {\n schema: typeof MAP_ROOT_SCHEMA\n shards: Record<string, string>\n} {\n const obj = asRecord(json, 'map root')\n if (obj.schema !== MAP_ROOT_SCHEMA) {\n throw new Error(`Invalid map root schema: ${String(obj.schema)}`)\n }\n if (obj.shards === null || typeof obj.shards !== 'object') {\n throw new Error('Invalid map root: shards must be an object')\n }\n return obj as {\n schema: typeof MAP_ROOT_SCHEMA\n shards: Record<string, string>\n }\n}\n\nexport function parseMapShard(json: unknown): {\n entries: Record<string, { contentType?: string; hash: string; size: number }>\n schema: typeof MAP_SHARD_SCHEMA\n} {\n const obj = asRecord(json, 'map shard')\n if (obj.schema !== MAP_SHARD_SCHEMA) {\n throw new Error(`Invalid map shard schema: ${String(obj.schema)}`)\n }\n return obj as {\n entries: Record<string, { contentType?: string; hash: string; size: number }>\n schema: typeof MAP_SHARD_SCHEMA\n }\n}\n", "import { canonicalHeadBytes } from '../publication/canonicalHead.ts'\nimport {\n CAS_PREFIX,\n DEFAULT_SHARD_HEX_CHARS,\n GENERATIONS_PREFIX,\n HEAD_KEY,\n MAP_SHARDS_PREFIX,\n STATUS_KEY,\n} from '../publication/constants.ts'\nimport { shardIdForKey as routeShard } from '../publication/shard.ts'\nimport type {\n GenerationManifest, HeadManifest, IndexerStatus,\n} from '../publication/types.ts'\nimport { hashBytesAsync } from './hash.ts'\nimport {\n parseGenerationManifest,\n parseHead,\n parseIndexerStatus,\n parseMapRoot,\n parseMapShard,\n} from './parse.ts'\n\nexport type FetchLike = (input: string, init?: { method?: string }) => Promise<{\n ok: boolean\n status: number\n arrayBuffer(): Promise<ArrayBuffer>\n json(): Promise<unknown>\n text(): Promise<string>\n}>\n\nexport interface PublicBases {\n index?: string\n state: string\n}\n\nexport interface VerifyPublishedViewResult {\n head: HeadManifest\n layout: 'full' | 'incremental-cas'\n manifest?: GenerationManifest\n rootShards?: Record<string, string>\n source?: GenerationManifest['source']\n status?: IndexerStatus\n}\n\nexport interface ResolveObjectResult {\n body: Uint8Array\n contentType?: string\n hash: string\n logicalKey: string\n publicUrl: string\n}\n\nfunction joinUrl(base: string, key: string): string {\n const b = base.replace(/\\/+$/, '')\n const k = key.replace(/^\\/+/, '')\n return `${b}/${k}`\n}\n\nasync function fetchJson(fetchImpl: FetchLike, url: string): Promise<unknown> {\n const res = await fetchImpl(url)\n if (!res.ok) throw new Error(`GET ${url} failed: ${res.status}`)\n return await res.json()\n}\n\nasync function fetchBytes(fetchImpl: FetchLike, url: string): Promise<Uint8Array> {\n const res = await fetchImpl(url)\n if (!res.ok) throw new Error(`GET ${url} failed: ${res.status}`)\n return new Uint8Array(await res.arrayBuffer())\n}\n\nexport function shardIdForKey(logicalKey: string, hexChars = DEFAULT_SHARD_HEX_CHARS): string {\n return routeShard(logicalKey, hexChars)\n}\n\nexport {\n hashBytesAsync,\n parseGenerationManifest,\n parseHead,\n parseIndexerStatus,\n parseMapRoot,\n parseMapShard,\n}\n\nasync function loadFullManifest(\n fetchImpl: FetchLike,\n bases: PublicBases,\n head: HeadManifest,\n): Promise<GenerationManifest> {\n const manifestUrl = joinUrl(bases.state, head.manifestKey)\n const manifestBytes = await fetchBytes(fetchImpl, manifestUrl)\n const actual = await hashBytesAsync(manifestBytes)\n if (actual !== head.manifestHash) {\n throw new Error(`Manifest hash mismatch: head=${head.manifestHash} actual=${actual}`)\n }\n const manifest = parseGenerationManifest(JSON.parse(new TextDecoder().decode(manifestBytes)))\n if (manifest.generation !== head.generation) {\n throw new Error('Manifest generation does not match head')\n }\n return manifest\n}\n\nasync function loadRootShards(\n fetchImpl: FetchLike,\n bases: PublicBases,\n head: HeadManifest,\n): Promise<Record<string, string>> {\n const rootUrl = joinUrl(bases.state, head.manifestKey)\n const rootBytes = await fetchBytes(fetchImpl, rootUrl)\n const actual = await hashBytesAsync(rootBytes)\n if (actual !== head.manifestHash) {\n throw new Error(`Root hash mismatch: head=${head.manifestHash} actual=${actual}`)\n }\n return parseMapRoot(JSON.parse(new TextDecoder().decode(rootBytes))).shards\n}\n\n/**\n * Fetch head (+ optional status), verify manifest/root integrity, optional\n * signature check. Does not download the full object set.\n */\nexport async function verifyPublishedView(options: {\n bases: PublicBases\n fetch: FetchLike\n includeStatus?: boolean\n verifySignature?: (canonical: Uint8Array, signature: string) => boolean | Promise<boolean>\n}): Promise<VerifyPublishedViewResult> {\n const headUrl = joinUrl(options.bases.state, HEAD_KEY)\n const head = parseHead(await fetchJson(options.fetch, headUrl))\n if (head.trust === 'signed') {\n if (options.verifySignature === undefined) {\n throw new Error('Signed head requires verifySignature callback')\n }\n if (head.signature === undefined) throw new Error('Signed head missing signature')\n const ok = await options.verifySignature(canonicalHeadBytes(head), head.signature)\n if (!ok) throw new Error('Head signature verification failed')\n }\n\n const layout = head.layout === 'incremental-cas' ? 'incremental-cas' : 'full'\n let manifest: GenerationManifest | undefined\n let rootShards: Record<string, string> | undefined\n let source: GenerationManifest['source'] | undefined\n\n if (layout === 'full') {\n manifest = await loadFullManifest(options.fetch, options.bases, head)\n source = manifest.source\n } else {\n rootShards = await loadRootShards(options.fetch, options.bases, head)\n }\n\n let status: IndexerStatus | undefined\n if (options.includeStatus === true) {\n try {\n status = parseIndexerStatus(\n await fetchJson(options.fetch, joinUrl(options.bases.state, STATUS_KEY)),\n )\n } catch {\n // status optional\n }\n }\n\n return {\n head,\n layout,\n ...(manifest !== undefined && { manifest }),\n ...(rootShards !== undefined && { rootShards }),\n ...(source !== undefined && { source }),\n ...(status !== undefined && { status }),\n }\n}\n\nasync function resolveIncrementalObject(options: {\n bases: PublicBases\n fetch: FetchLike\n head: HeadManifest\n logicalKey: string\n role: 'state' | 'index'\n shardHexChars?: number\n}): Promise<ResolveObjectResult> {\n const base = options.role === 'index'\n ? (options.bases.index ?? options.bases.state)\n : options.bases.state\n const rootBytes = await fetchBytes(\n options.fetch,\n joinUrl(options.bases.state, options.head.manifestKey),\n )\n if (await hashBytesAsync(rootBytes) !== options.head.manifestHash) {\n throw new Error('Map root hash mismatch')\n }\n const root = parseMapRoot(JSON.parse(new TextDecoder().decode(rootBytes)))\n const sid = shardIdForKey(options.logicalKey, options.shardHexChars)\n const shardHash = root.shards[sid]\n if (shardHash === undefined) throw new Error(`No shard for key \"${options.logicalKey}\"`)\n const shardKey = `${MAP_SHARDS_PREFIX}/${shardHash}.json`\n const shardBytes = await fetchBytes(options.fetch, joinUrl(options.bases.state, shardKey))\n if (await hashBytesAsync(shardBytes) !== shardHash) throw new Error('Shard hash mismatch')\n const shard = parseMapShard(JSON.parse(new TextDecoder().decode(shardBytes)))\n const entry = shard.entries[options.logicalKey]\n if (entry === undefined) throw new Error(`Key not found: ${options.logicalKey}`)\n const casKey = `${CAS_PREFIX}/${entry.hash}`\n const publicUrl = joinUrl(base, casKey)\n const body = await fetchBytes(options.fetch, publicUrl)\n if (await hashBytesAsync(body) !== entry.hash) {\n throw new Error(`Object hash mismatch for ${options.logicalKey}`)\n }\n return {\n body,\n hash: entry.hash,\n logicalKey: options.logicalKey,\n publicUrl,\n ...(entry.contentType !== undefined && { contentType: entry.contentType }),\n }\n}\n\n/**\n * Resolve and verify a single logical object under the current head without\n * downloading a full-generation object list (incremental: root+shard+cas).\n */\nexport async function resolveObject(options: {\n bases: PublicBases\n fetch: FetchLike\n head?: HeadManifest\n logicalKey: string\n role?: 'state' | 'index'\n shardHexChars?: number\n}): Promise<ResolveObjectResult> {\n const role = options.role ?? 'index'\n const head = options.head\n ?? parseHead(await fetchJson(options.fetch, joinUrl(options.bases.state, HEAD_KEY)))\n const logicalKey = options.logicalKey.replaceAll(/^\\/+/g, '')\n\n if (head.layout === 'incremental-cas') {\n return await resolveIncrementalObject({\n bases: options.bases,\n fetch: options.fetch,\n head,\n logicalKey,\n role,\n ...(options.shardHexChars !== undefined && { shardHexChars: options.shardHexChars }),\n })\n }\n\n const manifest = await loadFullManifest(options.fetch, options.bases, head)\n const ref = manifest.objects.find(o =>\n o.role === role && (o.key === logicalKey || o.key.endsWith(`/${logicalKey}`)\n || o.key === `${GENERATIONS_PREFIX}/${head.generation}/${logicalKey}`))\n if (ref === undefined) throw new Error(`Key not found in full manifest: ${logicalKey}`)\n const objectBase = ref.role === 'index'\n ? (options.bases.index ?? options.bases.state)\n : options.bases.state\n const publicUrl = ref.publicUrl ?? joinUrl(objectBase, ref.key)\n const body = await fetchBytes(options.fetch, publicUrl)\n if (await hashBytesAsync(body) !== ref.hash) {\n throw new Error(`Object hash mismatch for ${logicalKey}`)\n }\n return {\n body,\n hash: ref.hash,\n logicalKey,\n publicUrl,\n ...(ref.contentType !== undefined && { contentType: ref.contentType }),\n }\n}\n"],
|
|
5
|
-
"mappings": ";AAMO,SAAS,mBAAmB,MAAgC;AACjE,QAAM,UAAmC;AAAA,IACvC,QAAQ,KAAK;AAAA,IACb,YAAY,KAAK;AAAA,IACjB,aAAa,KAAK;AAAA,IAClB,cAAc,KAAK;AAAA,IACnB,aAAa,KAAK;AAAA,EACpB;AACA,MAAI,KAAK,uBAAuB,QAAW;AACzC,YAAQ,qBAAqB,KAAK;AAAA,EACpC;AACA,MAAI,KAAK,aAAa,OAAW,SAAQ,WAAW,KAAK;AACzD,MAAI,KAAK,UAAU,OAAW,SAAQ,QAAQ,KAAK;AACnD,MAAI,KAAK,WAAW,OAAW,SAAQ,SAAS,KAAK;AAErD,QAAM,UAAmC,CAAC;AAC1C,aAAW,OAAO;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAG;AACD,QAAI,OAAO,QAAS,SAAQ,GAAG,IAAI,QAAQ,GAAG;AAAA,EAChD;AACA,SAAO,IAAI,YAAY,EAAE,OAAO,GAAG,KAAK,UAAU,OAAO,CAAC;AAAA,CAAI;AAChE;;;
|
|
4
|
+
"sourcesContent": ["import type { HeadManifest } from './types.ts'\n\n/**\n * Canonical UTF-8 JSON bytes for head signing/verification. Excludes\n * `signature` and uses a fixed field order so Node and browser agree.\n */\nexport function canonicalHeadBytes(head: HeadManifest): Uint8Array {\n const payload: Record<string, unknown> = {\n schema: head.schema,\n generation: head.generation,\n manifestKey: head.manifestKey,\n manifestHash: head.manifestHash,\n publishedAt: head.publishedAt,\n }\n if (head.previousGeneration !== undefined) {\n payload.previousGeneration = head.previousGeneration\n }\n if (head.revision !== undefined) payload.revision = head.revision\n if (head.trust !== undefined) payload.trust = head.trust\n if (head.layout !== undefined) payload.layout = head.layout\n // Stable key order via explicit construction above (not Object key enum order).\n const ordered: Record<string, unknown> = {}\n for (const key of [\n 'schema',\n 'generation',\n 'manifestKey',\n 'manifestHash',\n 'publishedAt',\n 'previousGeneration',\n 'revision',\n 'trust',\n 'layout',\n ]) {\n if (key in payload) ordered[key] = payload[key]\n }\n return new TextEncoder().encode(`${JSON.stringify(ordered)}\\n`)\n}\n", "/**\nWell-known relative keys published by the coherent generation protocol.\n*/\nexport const HEAD_KEY = 'head.json'\nexport const STATUS_KEY = 'status.json'\nexport const PINS_KEY = 'pins.json'\nexport const GENERATIONS_PREFIX = 'generations'\n/**\nContent-addressed object bodies (incremental layout).\n*/\nexport const CAS_PREFIX = 'cas/sha256'\n/**\nSharded logical map roots (incremental layout).\n*/\nexport const MAP_ROOTS_PREFIX = 'map/roots'\n/**\nSharded logical map shards (incremental layout).\n*/\nexport const MAP_SHARDS_PREFIX = 'map/shards'\n/**\nSmall generation receipts for incremental layout.\n*/\nexport const RECEIPTS_PREFIX = 'receipts'\n\n/**\nCDN caching: immutable generation objects and manifests.\n*/\nexport const CACHE_CONTROL_IMMUTABLE = 'public, max-age=31536000, immutable'\n/**\nCDN caching: mutable head and status objects that must revalidate.\n*/\nexport const CACHE_CONTROL_REVALIDATE = 'public, max-age=0, must-revalidate'\n\nexport const GENERATION_MANIFEST_SCHEMA = 'network.aries.dapp.generation.manifest' as const\nexport const HEAD_MANIFEST_SCHEMA = 'network.aries.dapp.head' as const\nexport const INDEXER_STATUS_SCHEMA = 'network.aries.dapp.indexer.status' as const\nexport const PINS_SCHEMA = 'network.aries.dapp.pins' as const\nexport const MAP_ROOT_SCHEMA = 'network.aries.dapp.map.root' as const\nexport const MAP_SHARD_SCHEMA = 'network.aries.dapp.map.shard' as const\nexport const RECEIPT_SCHEMA = 'network.aries.dapp.generation.receipt' as const\n\n/**\nDefault shard width: first 2 hex chars of sha256(logicalKey) \u2192 256 shards.\n*/\nexport const DEFAULT_SHARD_HEX_CHARS = 2\n", "import { DEFAULT_SHARD_HEX_CHARS } from './constants.ts'\n\n/**\n * Shard routing id for a logical key. FNV-1a 32-bit, hex-padded \u2014 used only to\n * partition the logical map (not for content integrity). Must match between\n * writer and browser consumer (no crypto required).\n */\nexport function shardIdForKey(logicalKey: string, hexChars = DEFAULT_SHARD_HEX_CHARS): string {\n let h = 0x81_1C_9D_C5\n for (let i = 0; i < logicalKey.length; i++) {\n h ^= logicalKey.codePointAt(i)!\n h = Math.imul(h, 0x01_00_01_93)\n }\n return (h >>> 0).toString(16).padStart(8, '0').slice(0, hexChars)\n}\n", "/**\n * Browser-neutral SHA-256 via Web Crypto (`crypto.subtle`).\n * Available in modern browsers and Node \u226518 without Node crypto modules.\n */\n\nfunction bytesOf(body: string | Uint8Array): Uint8Array {\n return typeof body === 'string' ? new TextEncoder().encode(body) : body\n}\n\nfunction toHex(bytes: Uint8Array): string {\n let out = ''\n for (const b of bytes) out += b.toString(16).padStart(2, '0')\n return out\n}\n\nfunction requireSubtle(): SubtleCrypto {\n const subtle = globalThis.crypto?.subtle\n if (subtle === undefined) {\n throw new Error('Web Crypto subtle API is required for consumer hashing')\n }\n return subtle\n}\n\nexport async function hashBytesAsync(body: string | Uint8Array): Promise<string> {\n const data = bytesOf(body)\n const digest = await requireSubtle().digest(\n 'SHA-256',\n data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) as ArrayBuffer,\n )\n return toHex(new Uint8Array(digest))\n}\n", "import {\n GENERATION_MANIFEST_SCHEMA,\n HEAD_MANIFEST_SCHEMA,\n INDEXER_STATUS_SCHEMA,\n MAP_ROOT_SCHEMA,\n MAP_SHARD_SCHEMA,\n} from '../publication/constants.ts'\nimport type {\n GenerationManifest, HeadManifest, IndexerStatus,\n} from '../publication/types.ts'\n\nfunction asRecord(value: unknown, label: string): Record<string, unknown> {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`Invalid ${label}: expected object`)\n }\n return value as Record<string, unknown>\n}\n\nfunction requireString(obj: Record<string, unknown>, key: string, label: string): string {\n const v = obj[key]\n if (typeof v !== 'string' || v.length === 0) {\n throw new Error(`Invalid ${label}: missing string \"${key}\"`)\n }\n return v\n}\n\nexport function parseHead(json: unknown): HeadManifest {\n const obj = asRecord(json, 'head')\n if (obj.schema !== HEAD_MANIFEST_SCHEMA) {\n throw new Error(`Invalid head schema: ${String(obj.schema)}`)\n }\n return {\n schema: HEAD_MANIFEST_SCHEMA,\n generation: requireString(obj, 'generation', 'head'),\n manifestKey: requireString(obj, 'manifestKey', 'head'),\n manifestHash: requireString(obj, 'manifestHash', 'head'),\n publishedAt: requireString(obj, 'publishedAt', 'head'),\n ...(typeof obj.previousGeneration === 'string'\n && { previousGeneration: obj.previousGeneration }),\n ...(typeof obj.revision === 'number' && { revision: obj.revision }),\n ...(obj.trust === 'trusted-origin' || obj.trust === 'signed'\n ? { trust: obj.trust }\n : {}),\n ...(typeof obj.signature === 'string' && { signature: obj.signature }),\n ...(obj.layout === 'full' || obj.layout === 'incremental-cas'\n ? { layout: obj.layout }\n : {}),\n }\n}\n\nexport function parseGenerationManifest(json: unknown): GenerationManifest {\n const obj = asRecord(json, 'manifest')\n if (obj.schema !== GENERATION_MANIFEST_SCHEMA) {\n throw new Error(`Invalid generation manifest schema: ${String(obj.schema)}`)\n }\n if (!Array.isArray(obj.objects)) {\n throw new TypeError('Invalid generation manifest: objects must be an array')\n }\n return obj as unknown as GenerationManifest\n}\n\nexport function parseIndexerStatus(json: unknown): IndexerStatus {\n const obj = asRecord(json, 'status')\n if (obj.schema !== INDEXER_STATUS_SCHEMA) {\n throw new Error(`Invalid status schema: ${String(obj.schema)}`)\n }\n return obj as unknown as IndexerStatus\n}\n\nexport function parseMapRoot(json: unknown): {\n schema: typeof MAP_ROOT_SCHEMA\n shards: Record<string, string>\n} {\n const obj = asRecord(json, 'map root')\n if (obj.schema !== MAP_ROOT_SCHEMA) {\n throw new Error(`Invalid map root schema: ${String(obj.schema)}`)\n }\n if (obj.shards === null || typeof obj.shards !== 'object') {\n throw new Error('Invalid map root: shards must be an object')\n }\n return obj as {\n schema: typeof MAP_ROOT_SCHEMA\n shards: Record<string, string>\n }\n}\n\nexport function parseMapShard(json: unknown): {\n entries: Record<string, { contentType?: string; hash: string; size: number }>\n schema: typeof MAP_SHARD_SCHEMA\n} {\n const obj = asRecord(json, 'map shard')\n if (obj.schema !== MAP_SHARD_SCHEMA) {\n throw new Error(`Invalid map shard schema: ${String(obj.schema)}`)\n }\n return obj as {\n entries: Record<string, { contentType?: string; hash: string; size: number }>\n schema: typeof MAP_SHARD_SCHEMA\n }\n}\n", "import { canonicalHeadBytes } from '../publication/canonicalHead.ts'\nimport {\n CAS_PREFIX,\n DEFAULT_SHARD_HEX_CHARS,\n GENERATIONS_PREFIX,\n HEAD_KEY,\n MAP_SHARDS_PREFIX,\n STATUS_KEY,\n} from '../publication/constants.ts'\nimport { shardIdForKey as routeShard } from '../publication/shard.ts'\nimport type {\n GenerationManifest, HeadManifest, IndexerStatus,\n} from '../publication/types.ts'\nimport { hashBytesAsync } from './hash.ts'\nimport {\n parseGenerationManifest,\n parseHead,\n parseIndexerStatus,\n parseMapRoot,\n parseMapShard,\n} from './parse.ts'\n\nexport type FetchLike = (input: string, init?: { method?: string }) => Promise<{\n ok: boolean\n status: number\n arrayBuffer(): Promise<ArrayBuffer>\n json(): Promise<unknown>\n text(): Promise<string>\n}>\n\nexport interface PublicBases {\n index?: string\n state: string\n}\n\nexport interface VerifyPublishedViewResult {\n head: HeadManifest\n layout: 'full' | 'incremental-cas'\n manifest?: GenerationManifest\n rootShards?: Record<string, string>\n source?: GenerationManifest['source']\n status?: IndexerStatus\n}\n\nexport interface ResolveObjectResult {\n body: Uint8Array\n contentType?: string\n hash: string\n logicalKey: string\n publicUrl: string\n}\n\nfunction joinUrl(base: string, key: string): string {\n const b = base.replace(/\\/+$/, '')\n const k = key.replace(/^\\/+/, '')\n return `${b}/${k}`\n}\n\nasync function fetchJson(fetchImpl: FetchLike, url: string): Promise<unknown> {\n const res = await fetchImpl(url)\n if (!res.ok) throw new Error(`GET ${url} failed: ${res.status}`)\n return await res.json()\n}\n\nasync function fetchBytes(fetchImpl: FetchLike, url: string): Promise<Uint8Array> {\n const res = await fetchImpl(url)\n if (!res.ok) throw new Error(`GET ${url} failed: ${res.status}`)\n return new Uint8Array(await res.arrayBuffer())\n}\n\nexport function shardIdForKey(logicalKey: string, hexChars = DEFAULT_SHARD_HEX_CHARS): string {\n return routeShard(logicalKey, hexChars)\n}\n\nexport {\n hashBytesAsync,\n parseGenerationManifest,\n parseHead,\n parseIndexerStatus,\n parseMapRoot,\n parseMapShard,\n}\n\nasync function loadFullManifest(\n fetchImpl: FetchLike,\n bases: PublicBases,\n head: HeadManifest,\n): Promise<GenerationManifest> {\n const manifestUrl = joinUrl(bases.state, head.manifestKey)\n const manifestBytes = await fetchBytes(fetchImpl, manifestUrl)\n const actual = await hashBytesAsync(manifestBytes)\n if (actual !== head.manifestHash) {\n throw new Error(`Manifest hash mismatch: head=${head.manifestHash} actual=${actual}`)\n }\n const manifest = parseGenerationManifest(JSON.parse(new TextDecoder().decode(manifestBytes)))\n if (manifest.generation !== head.generation) {\n throw new Error('Manifest generation does not match head')\n }\n return manifest\n}\n\nasync function loadRootShards(\n fetchImpl: FetchLike,\n bases: PublicBases,\n head: HeadManifest,\n): Promise<Record<string, string>> {\n const rootUrl = joinUrl(bases.state, head.manifestKey)\n const rootBytes = await fetchBytes(fetchImpl, rootUrl)\n const actual = await hashBytesAsync(rootBytes)\n if (actual !== head.manifestHash) {\n throw new Error(`Root hash mismatch: head=${head.manifestHash} actual=${actual}`)\n }\n return parseMapRoot(JSON.parse(new TextDecoder().decode(rootBytes))).shards\n}\n\n/**\n * Fetch head (+ optional status), verify manifest/root integrity, optional\n * signature check. Does not download the full object set.\n */\nexport async function verifyPublishedView(options: {\n bases: PublicBases\n fetch: FetchLike\n includeStatus?: boolean\n verifySignature?: (canonical: Uint8Array, signature: string) => boolean | Promise<boolean>\n}): Promise<VerifyPublishedViewResult> {\n const headUrl = joinUrl(options.bases.state, HEAD_KEY)\n const head = parseHead(await fetchJson(options.fetch, headUrl))\n if (head.trust === 'signed') {\n if (options.verifySignature === undefined) {\n throw new Error('Signed head requires verifySignature callback')\n }\n if (head.signature === undefined) throw new Error('Signed head missing signature')\n const ok = await options.verifySignature(canonicalHeadBytes(head), head.signature)\n if (!ok) throw new Error('Head signature verification failed')\n }\n\n const layout = head.layout === 'incremental-cas' ? 'incremental-cas' : 'full'\n let manifest: GenerationManifest | undefined\n let rootShards: Record<string, string> | undefined\n let source: GenerationManifest['source'] | undefined\n\n if (layout === 'full') {\n manifest = await loadFullManifest(options.fetch, options.bases, head)\n source = manifest.source\n } else {\n rootShards = await loadRootShards(options.fetch, options.bases, head)\n }\n\n let status: IndexerStatus | undefined\n if (options.includeStatus === true) {\n try {\n status = parseIndexerStatus(\n await fetchJson(options.fetch, joinUrl(options.bases.state, STATUS_KEY)),\n )\n } catch {\n // status optional\n }\n }\n\n return {\n head,\n layout,\n ...(manifest !== undefined && { manifest }),\n ...(rootShards !== undefined && { rootShards }),\n ...(source !== undefined && { source }),\n ...(status !== undefined && { status }),\n }\n}\n\nasync function resolveIncrementalObject(options: {\n bases: PublicBases\n fetch: FetchLike\n head: HeadManifest\n logicalKey: string\n role: 'state' | 'index'\n shardHexChars?: number\n}): Promise<ResolveObjectResult> {\n const base = options.role === 'index'\n ? (options.bases.index ?? options.bases.state)\n : options.bases.state\n const rootBytes = await fetchBytes(\n options.fetch,\n joinUrl(options.bases.state, options.head.manifestKey),\n )\n if (await hashBytesAsync(rootBytes) !== options.head.manifestHash) {\n throw new Error('Map root hash mismatch')\n }\n const root = parseMapRoot(JSON.parse(new TextDecoder().decode(rootBytes)))\n const sid = shardIdForKey(options.logicalKey, options.shardHexChars)\n const shardHash = root.shards[sid]\n if (shardHash === undefined) throw new Error(`No shard for key \"${options.logicalKey}\"`)\n const shardKey = `${MAP_SHARDS_PREFIX}/${shardHash}.json`\n const shardBytes = await fetchBytes(options.fetch, joinUrl(options.bases.state, shardKey))\n if (await hashBytesAsync(shardBytes) !== shardHash) throw new Error('Shard hash mismatch')\n const shard = parseMapShard(JSON.parse(new TextDecoder().decode(shardBytes)))\n const entry = shard.entries[options.logicalKey]\n if (entry === undefined) throw new Error(`Key not found: ${options.logicalKey}`)\n const casKey = `${CAS_PREFIX}/${entry.hash}`\n const publicUrl = joinUrl(base, casKey)\n const body = await fetchBytes(options.fetch, publicUrl)\n if (await hashBytesAsync(body) !== entry.hash) {\n throw new Error(`Object hash mismatch for ${options.logicalKey}`)\n }\n return {\n body,\n hash: entry.hash,\n logicalKey: options.logicalKey,\n publicUrl,\n ...(entry.contentType !== undefined && { contentType: entry.contentType }),\n }\n}\n\n/**\n * Resolve and verify a single logical object under the current head without\n * downloading a full-generation object list (incremental: root+shard+cas).\n */\nexport async function resolveObject(options: {\n bases: PublicBases\n fetch: FetchLike\n head?: HeadManifest\n logicalKey: string\n role?: 'state' | 'index'\n shardHexChars?: number\n}): Promise<ResolveObjectResult> {\n const role = options.role ?? 'index'\n const head = options.head\n ?? parseHead(await fetchJson(options.fetch, joinUrl(options.bases.state, HEAD_KEY)))\n const logicalKey = options.logicalKey.replaceAll(/^\\/+/g, '')\n\n if (head.layout === 'incremental-cas') {\n return await resolveIncrementalObject({\n bases: options.bases,\n fetch: options.fetch,\n head,\n logicalKey,\n role,\n ...(options.shardHexChars !== undefined && { shardHexChars: options.shardHexChars }),\n })\n }\n\n const manifest = await loadFullManifest(options.fetch, options.bases, head)\n const ref = manifest.objects.find(o =>\n o.role === role && (o.key === logicalKey || o.key.endsWith(`/${logicalKey}`)\n || o.key === `${GENERATIONS_PREFIX}/${head.generation}/${logicalKey}`))\n if (ref === undefined) throw new Error(`Key not found in full manifest: ${logicalKey}`)\n const objectBase = ref.role === 'index'\n ? (options.bases.index ?? options.bases.state)\n : options.bases.state\n const publicUrl = ref.publicUrl ?? joinUrl(objectBase, ref.key)\n const body = await fetchBytes(options.fetch, publicUrl)\n if (await hashBytesAsync(body) !== ref.hash) {\n throw new Error(`Object hash mismatch for ${logicalKey}`)\n }\n return {\n body,\n hash: ref.hash,\n logicalKey,\n publicUrl,\n ...(ref.contentType !== undefined && { contentType: ref.contentType }),\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["shardIdForKey", "shardIdForKey"]
|
|
7
7
|
}
|
package/dist/node/index.mjs
CHANGED
|
@@ -182,11 +182,15 @@ var DappActor = class extends PeriodicActor {
|
|
|
182
182
|
_data;
|
|
183
183
|
_index;
|
|
184
184
|
_state;
|
|
185
|
-
/**
|
|
185
|
+
/**
|
|
186
|
+
Dapp actors require a logger in the locator context (see {@link DappContext}).
|
|
187
|
+
*/
|
|
186
188
|
get logger() {
|
|
187
189
|
return assertEx(super.logger, () => `Logger is required in context for actor ${this.name}.`);
|
|
188
190
|
}
|
|
189
|
-
/**
|
|
191
|
+
/**
|
|
192
|
+
Reduce cadence: `reduceIntervalMs` names the interval in dapp configs.
|
|
193
|
+
*/
|
|
190
194
|
get intervalMs() {
|
|
191
195
|
return this.params.reduceIntervalMs ?? DEFAULT_REDUCE_INTERVAL_MS;
|
|
192
196
|
}
|
|
@@ -203,7 +207,9 @@ var DappActor = class extends PeriodicActor {
|
|
|
203
207
|
`DappActor started: reducer '${this.params.reducer.name}' every ${this.intervalMs}ms (first run in ${this.firstRunDelayMs}ms)`
|
|
204
208
|
);
|
|
205
209
|
}
|
|
206
|
-
/**
|
|
210
|
+
/**
|
|
211
|
+
Failure side-channel: publish durable failure status (count already incremented).
|
|
212
|
+
*/
|
|
207
213
|
async onPassError(error) {
|
|
208
214
|
await this.safePublishStatus(void 0, error);
|
|
209
215
|
}
|