@wovin/core 0.3.3 → 0.3.5
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/applog/applog-utils.d.ts +12 -1
- package/dist/applog/applog-utils.d.ts.map +1 -1
- package/dist/applog.js +5 -1
- package/dist/{chunk-H4YVJKB7.js → chunk-AFRRFDNL.js} +2 -2
- package/dist/{chunk-BIYQEX3N.js → chunk-B22AIVJH.js} +2 -2
- package/dist/{chunk-6CSJTSQP.js → chunk-EZZVLYYC.js} +3 -3
- package/dist/{chunk-H3JNNTVP.js → chunk-IC6WD7RV.js} +27 -6
- package/dist/chunk-IC6WD7RV.js.map +1 -0
- package/dist/{chunk-4MKPGQIM.js → chunk-OUQE6LG4.js} +138 -64
- package/dist/chunk-OUQE6LG4.js.map +1 -0
- package/dist/{chunk-N7SEGHU4.js → chunk-PNNJMXZI.js} +33 -24
- package/dist/chunk-PNNJMXZI.js.map +1 -0
- package/dist/{chunk-N5QPZNKD.js → chunk-PSIMJH6F.js} +3 -3
- package/dist/index.js +11 -7
- package/dist/ipfs.js +4 -4
- package/dist/ipns/ipns-record.d.ts.map +1 -1
- package/dist/ipns/ipns-watcher.d.ts.map +1 -1
- package/dist/ipns.js +6 -8
- package/dist/ipns.js.map +1 -1
- package/dist/pubsub/snap-push.d.ts.map +1 -1
- package/dist/pubsub.js +4 -4
- package/dist/query/basic.d.ts.map +1 -1
- package/dist/query.js +3 -3
- package/dist/retrieve.js +4 -4
- package/dist/thread/basic.d.ts +18 -1
- package/dist/thread/basic.d.ts.map +1 -1
- package/dist/thread/mapped.d.ts +3 -1
- package/dist/thread/mapped.d.ts.map +1 -1
- package/dist/thread/utils.d.ts.map +1 -1
- package/dist/thread/writeable.d.ts.map +1 -1
- package/dist/thread.js +1 -1
- package/dist/viewmodel/index.js +2 -2
- package/package.json +1 -1
- package/src/applog/applog-utils.ts +33 -1
- package/src/ipns/ipns-record.test.ts +72 -0
- package/src/ipns/ipns-record.ts +23 -8
- package/src/ipns/ipns-watcher.ts +10 -11
- package/src/pubsub/snap-push.ts +25 -3
- package/src/query/basic.ts +124 -81
- package/src/thread/basic.ts +52 -5
- package/src/thread/insertMissing-perf.test.ts +95 -0
- package/src/thread/mapped.ts +25 -5
- package/src/thread/membership-cache.test.ts +133 -0
- package/src/thread/utils.ts +5 -5
- package/src/thread/writeable.ts +2 -1
- package/dist/chunk-4MKPGQIM.js.map +0 -1
- package/dist/chunk-H3JNNTVP.js.map +0 -1
- package/dist/chunk-N7SEGHU4.js.map +0 -1
- /package/dist/{chunk-H4YVJKB7.js.map → chunk-AFRRFDNL.js.map} +0 -0
- /package/dist/{chunk-BIYQEX3N.js.map → chunk-B22AIVJH.js.map} +0 -0
- /package/dist/{chunk-6CSJTSQP.js.map → chunk-EZZVLYYC.js.map} +0 -0
- /package/dist/{chunk-N5QPZNKD.js.map → chunk-PSIMJH6F.js.map} +0 -0
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import type { Applog, ApplogValue, DatalogQueryPattern, DatalogQueryResultEntry, ResultContext, SearchContext, ValueOrMatcher } from './datom-types.ts';
|
|
1
|
+
import type { Applog, ApplogOfSomeSort, ApplogValue, DatalogQueryPattern, DatalogQueryResultEntry, ResultContext, SearchContext, ValueOrMatcher } from './datom-types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* One-line, bounded summary of a single applog — enough to trace it in logs
|
|
4
|
+
* (`en/at=vl@ts#cid`) without dumping the full object (and, for arrays, the whole thread).
|
|
5
|
+
* Handles encrypted applogs and falsy entries so it's safe on error paths.
|
|
6
|
+
*/
|
|
7
|
+
export declare const applogSummary: (log: ApplogOfSomeSort | null | undefined) => string;
|
|
8
|
+
/**
|
|
9
|
+
* Bounded summary of an applog array: `[count] first, few, summaries …+N`.
|
|
10
|
+
* Keeps enough identity to debug (which logs, how many) while preventing log explosion.
|
|
11
|
+
*/
|
|
12
|
+
export declare const applogsSummary: (logs: readonly (ApplogOfSomeSort | null | undefined)[] | null | undefined, sample?: number) => string;
|
|
2
13
|
export declare const isoDateStrCompare: (strA: string, strB: string, dir?: "asc" | "desc") => number;
|
|
3
14
|
export declare const objEqualByKeys: (keys: string[], objA: object, objB: object) => boolean;
|
|
4
15
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applog-utils.d.ts","sourceRoot":"","sources":["../../src/applog/applog-utils.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACX,MAAM,
|
|
1
|
+
{"version":3,"file":"applog-utils.d.ts","sourceRoot":"","sources":["../../src/applog/applog-utils.ts"],"names":[],"mappings":"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"}
|
package/dist/applog.js
CHANGED
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
Nullable,
|
|
12
12
|
URL,
|
|
13
13
|
actualize,
|
|
14
|
+
applogSummary,
|
|
15
|
+
applogsSummary,
|
|
14
16
|
areApplogsEqual,
|
|
15
17
|
arrStats,
|
|
16
18
|
arraysContainSameElements,
|
|
@@ -52,7 +54,7 @@ import {
|
|
|
52
54
|
withAg,
|
|
53
55
|
withPvFrom,
|
|
54
56
|
withTs
|
|
55
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-OUQE6LG4.js";
|
|
56
58
|
import "./chunk-ZAADLBSB.js";
|
|
57
59
|
export {
|
|
58
60
|
AppLogNoCidTB,
|
|
@@ -66,6 +68,8 @@ export {
|
|
|
66
68
|
Nullable,
|
|
67
69
|
URL,
|
|
68
70
|
actualize,
|
|
71
|
+
applogSummary,
|
|
72
|
+
applogsSummary,
|
|
69
73
|
areApplogsEqual,
|
|
70
74
|
arrStats,
|
|
71
75
|
arraysContainSameElements,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
cyrb53hash,
|
|
3
3
|
ensureTsPvAndFinalizeApplog
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-OUQE6LG4.js";
|
|
5
5
|
|
|
6
6
|
// src/pubsub/pub-pull.ts
|
|
7
7
|
import { Logger } from "besonders-logger";
|
|
@@ -37,4 +37,4 @@ export {
|
|
|
37
37
|
isSubscription,
|
|
38
38
|
agentToShortHash
|
|
39
39
|
};
|
|
40
|
-
//# sourceMappingURL=chunk-
|
|
40
|
+
//# sourceMappingURL=chunk-AFRRFDNL.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
areCidsEqual
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OUQE6LG4.js";
|
|
4
4
|
|
|
5
5
|
// src/ipfs/fetch-snapshot-chain.ts
|
|
6
6
|
import * as dagJson from "@ipld/dag-json";
|
|
@@ -83,4 +83,4 @@ function createMemoryBlockStore() {
|
|
|
83
83
|
export {
|
|
84
84
|
fetchSnapshotChainUntil
|
|
85
85
|
};
|
|
86
|
-
//# sourceMappingURL=chunk-
|
|
86
|
+
//# sourceMappingURL=chunk-B22AIVJH.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
unchunkApplogsBlock
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IC6WD7RV.js";
|
|
4
4
|
import {
|
|
5
5
|
areCidsEqual,
|
|
6
6
|
removeDuplicateAppLogs
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-OUQE6LG4.js";
|
|
8
8
|
|
|
9
9
|
// src/retrieve/update-thread.ts
|
|
10
10
|
import * as dagJson from "@ipld/dag-json";
|
|
@@ -141,4 +141,4 @@ export {
|
|
|
141
141
|
withBlockCache,
|
|
142
142
|
updateThreadFromSnapshot
|
|
143
143
|
};
|
|
144
|
-
//# sourceMappingURL=chunk-
|
|
144
|
+
//# sourceMappingURL=chunk-EZZVLYYC.js.map
|
|
@@ -3,16 +3,17 @@ import {
|
|
|
3
3
|
} from "./chunk-YDAKBU6Q.js";
|
|
4
4
|
import {
|
|
5
5
|
lastWriteWins
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PNNJMXZI.js";
|
|
7
7
|
import {
|
|
8
8
|
anyOf,
|
|
9
|
+
applogsSummary,
|
|
9
10
|
areCidsEqual,
|
|
10
11
|
encodeBlockOriginal,
|
|
11
12
|
ensureTsPvAndFinalizeApplog,
|
|
12
13
|
getLogsFromThread,
|
|
13
14
|
prepareForPub,
|
|
14
15
|
rollingFilter
|
|
15
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-OUQE6LG4.js";
|
|
16
17
|
|
|
17
18
|
// src/pubsub/snap-push.ts
|
|
18
19
|
import * as dagJson2 from "@ipld/dag-json";
|
|
@@ -333,10 +334,30 @@ async function prepareSnapshotForPush(agent, appThread, threadToPublish, share,
|
|
|
333
334
|
const applogsToEncode = keepTruthy(maybeEncryptedApplogs);
|
|
334
335
|
const infologsToEncode = keepTruthy(infoLogs);
|
|
335
336
|
if (!applogsToEncode.length) {
|
|
336
|
-
throw ERROR2("no valid applogs", {
|
|
337
|
+
throw ERROR2("no valid applogs", {
|
|
338
|
+
agent: agent.did,
|
|
339
|
+
prevSnapCID: prevSnapCID?.toString(),
|
|
340
|
+
counts: {
|
|
341
|
+
rawApplogs: maybeEncryptedApplogs.length,
|
|
342
|
+
keptApplogs: applogsToEncode.length,
|
|
343
|
+
rawInfo: infoLogs.length,
|
|
344
|
+
keptInfo: infologsToEncode.length
|
|
345
|
+
},
|
|
346
|
+
rawApplogsSample: applogsSummary(maybeEncryptedApplogs)
|
|
347
|
+
});
|
|
337
348
|
}
|
|
338
349
|
if (!infologsToEncode.length) {
|
|
339
|
-
throw ERROR2("no valid infologs", {
|
|
350
|
+
throw ERROR2("no valid infologs", {
|
|
351
|
+
agent: agent.did,
|
|
352
|
+
prevSnapCID: prevSnapCID?.toString(),
|
|
353
|
+
counts: {
|
|
354
|
+
rawApplogs: maybeEncryptedApplogs.length,
|
|
355
|
+
keptApplogs: applogsToEncode.length,
|
|
356
|
+
rawInfo: infoLogs.length,
|
|
357
|
+
keptInfo: infologsToEncode.length
|
|
358
|
+
},
|
|
359
|
+
rawInfoSample: applogsSummary(infoLogs)
|
|
360
|
+
});
|
|
340
361
|
}
|
|
341
362
|
const encodedSnapshot = await encodeSnapshotAsCar(agent, applogsToEncode, infologsToEncode, prevSnapCID, prevCounter);
|
|
342
363
|
DEBUG2("inPrepareSnapshotForPush", { encodedSnapshot });
|
|
@@ -406,7 +427,7 @@ function isSnapBlockChunks(block) {
|
|
|
406
427
|
}
|
|
407
428
|
async function encodeSnapshotApplogsAsCar(applogs) {
|
|
408
429
|
const encoded = await encodeApplogsAsIPLD(applogs);
|
|
409
|
-
if (!encoded) throw ERROR2("invalid applogs cannot continue", {
|
|
430
|
+
if (!encoded) throw ERROR2("invalid applogs cannot continue", { encoded, applogs: applogsSummary(applogs) });
|
|
410
431
|
const { cids, encodedApplogs } = encoded;
|
|
411
432
|
const root = { applogs: cids };
|
|
412
433
|
const encodedRoot = await encodeBlockOriginal(root);
|
|
@@ -445,4 +466,4 @@ export {
|
|
|
445
466
|
collectDagBlocks,
|
|
446
467
|
streamReaderToIterable
|
|
447
468
|
};
|
|
448
|
-
//# sourceMappingURL=chunk-
|
|
469
|
+
//# sourceMappingURL=chunk-IC6WD7RV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pubsub/snap-push.ts","../src/ipfs/car.ts"],"sourcesContent":["import * as dagJson from '@ipld/dag-json'\nimport { Logger } from 'besonders-logger'\nimport { CID } from 'multiformats/cid'\nimport stringify from 'safe-stable-stringify'\nimport { ensureTsPvAndFinalizeApplog } from '../applog/applog-helpers.ts'\nimport { applogsSummary } from '../applog/applog-utils.ts'\nimport type {\n\tApplog,\n\tApplogArrayMaybeEncrypted,\n\tApplogArrayMaybeEncryptedRO,\n\tApplogArrayNoCIDMaybeEncryptedRO,\n\tApplogEnc,\n\tApplogEncNoCid,\n\tCidString,\n} from '../applog/datom-types.ts'\nimport { BlockStoreish, DecodedCar, getDecodedBlock, makeCarBlob } from '../ipfs/car.ts'\nimport { encodeBlockOriginal, prepareForPub } from '../ipfs/ipfs-utils.ts'\nimport { lastWriteWins } from './../query/basic.ts'\nimport { anyOf } from '../query/matchers.ts'\nimport { ApplogsOrThread, getLogsFromThread, Thread } from '../thread.ts'\nimport { rollingFilter } from '../thread/filters.ts'\nimport { keepTruthy } from '../utils.ts'\nimport type { AppAgent, IShare, SnapBlockChunks, SnapBlockLogs, SnapBlockLogsOrChunks } from './pubsub-types.ts'\n\nconst { WARN, LOG, DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.INFO) // eslint-disable-line no-unused-vars\n\n// export const neverEncryptAttrs = [\n// \t'agent/jwkd',\n// \t'agent/appAgent',\n// \t'pub/encryptedFor',\n// \t'pub/sharedKey',\n// ]\n\n// export interface WovinPublicationInfo {\n// \tid: string\n// }\n\nexport async function prepareSnapshotForPush(\n\tagent: AppAgent,\n\tappThread: Thread,\n\tthreadToPublish: ApplogsOrThread,\n\tshare: IShare,\n\tprevSnapCID: CID | null,\n\tprevCounter: number | null,\n) {\n\tif (prevCounter !== null && !prevSnapCID) {\n\t\tthrow ERROR('[prepareSnapshotForPush] prevCounter provided without prevSnapCID')\n\t}\n\t// TODO prevent publish if there is no new info\n\tlet logsToPublish = getLogsFromThread(threadToPublish)\n\n\t// const logsFromLastPush = await getLogsFromPub(publication)\n\t// logsToPublish = logsToPublish.filter(eachLog => !logsFromLastPush.includes(eachLog.cid)) // TODO deep compare includes\n\t// const prevPushCIDs = [\n\t// \tpublication.lastCID,\n\t// \t//TODO add this one and update the publication data after push\n\t// ]\n\t// const includedLogCIDs = [\n\t// \t'full array of CIDS from all previous pushes'\n\t// ]\n\n\tDEBUG(`[preparePubForPush] Collected ${logsToPublish.length} logs :`, {\n\t\tlogsToPublish,\n\t\tthreadOrLogsCount: (threadToPublish as any).nameAndSizeUntracked || (`[${(threadToPublish as any).length}]`),\n\t})\n\n\tconst { sharedAgents, sharedKeyMap, sharedKey, pubCounter } = share ?? {}\n\n\tconst getExistingOrNewLog = (thread: Thread, share: IShare, ag: string, at: string, vl) => {\n\t\tlet logInQuestion = rollingFilter(lastWriteWins(thread), { en: share.id, at }).latestLog\n\t\tif (!logInQuestion && vl !== undefined) {\n\t\t\tlogInQuestion = ensureTsPvAndFinalizeApplog({ ag, en: share.id, at, vl }, thread)\n\t\t}\n\t\treturn logInQuestion // can be undefined if the passed vl is undefined and the log is not found\n\t}\n\tconst shareNameLog = getExistingOrNewLog(appThread, share, agent.ag, 'share/name', share.name)\n\n\t// ? using did as it is derived from the same ecdh in note3 and part of the minimal AppAgent type required here in wovin core\n\tconst shareCounterLog = getExistingOrNewLog(appThread, share, agent.ag, 'share/counter', `${agent.did}<::>${pubCounter}`)\n\t// ? discuss if this works to bind the counter to a specific derivation key - did is not necessarily derived from the same key by all lib users\n\n\tconst encryptApplog = async (applog: Applog, keyToUse: CryptoKey): Promise<Uint8Array> => {\n\t\tconst { log: eachLog, cid } = prepareForPub(applog) // without cid\n\t\tconst enc = new TextEncoder()\n\t\tconst stringified = stringify(eachLog)\n\t\tconst stringifiedEncodedAppLogPayload = enc.encode(stringified) // TODO: consider encodeToDagJson instead\n\t\tVERBOSE('[odd]', { eachLog, stringified, stringifiedEncodedAppLogPayload })\n\n\t\ttry {\n\t\t\t// @ts-expect-error\n\t\t\tconst encPayload = await agent.crypto?.aes.encrypt(stringifiedEncodedAppLogPayload, keyToUse, 'AES-GCM')\n\t\t\t// TODO get rid of odd down here\n\t\t\tVERBOSE('[odd] encrypted length:', stringifiedEncodedAppLogPayload.length, { encPayload })\n\t\t\treturn encPayload\n\t\t} catch (err) {\n\t\t\tthrow ERROR('FAILED TO ENC payload length:', stringifiedEncodedAppLogPayload.length, { err })\n\t\t}\n\n\t\t// const decrypted = await decryptWithAesSharedKey(encPayload, keyToUse, 'string')\n\t}\n\n\tlet maybeEncryptedApplogs: ApplogEncNoCid[] | readonly Applog[]\n\tconst encryptedApplogs = [] as { enc: Uint8Array }[]\n\tconst agentSharedKeyLogs = []\n\tif (sharedAgents) { // encrypt all Applogs\n\t\tif (!sharedKey || !sharedKeyMap) {\n\t\t\tthrow ERROR('sharedAgents but no Keys/Map', { sharedAgents, sharedKeyMap, sharedKey })\n\t\t}\n\t\tVERBOSE('encrypting', { sharedAgents, sharedKeyMap })\n\n\t\tfor (const [eachAgent, eachEncKey] of Array.from(sharedKeyMap.entries())) {\n\t\t\tVERBOSE('adding key', { eachAgent, eachEncKey })\n\t\t\tagentSharedKeyLogs.push({\n\t\t\t\tag: agent.ag,\n\t\t\t\ten: eachAgent,\n\t\t\t\tat: 'share/sharedKey',\n\t\t\t\tvl: eachEncKey, // these are encrypted with the derived key from the local agent private and remote agent public keys\n\t\t\t})\n\t\t}\n\t\t// const encryptedForLogs = await insertApplogsInAppDB(agentSharedKeyLogs)\n\t\t// DEBUG(`[publish] adding agentSharedKeyLogs:`, encryptedForLogs)\n\t\tconst CIDlist: { cid: CidString; encCID?: CidString }[] = []\n\t\tconst pubCIDmap: Record<CidString, typeof CIDlist> = {}\n\t\t// TODO ensure that all needed keys are in\n\t\tfor (const eachLog of logsToPublish) {\n\t\t\tVERBOSE('[crypto] encrypting ', { eachLog, sharedKey })\n\t\t\t// try {\n\t\t\tconst encPayload = await encryptApplog(eachLog, sharedKey)\n\t\t\tDEBUG('[crypto] encrypted ', { eachLog, encPayload, sharedKey })\n\t\t\t// } catch (err) {\n\t\t\t// \t// its already traced in encryptAndTestDecrypt\n\t\t\t// \t// continue\n\t\t\t// }\n\t\t\tencryptedApplogs.push({ enc: encPayload })\n\t\t}\n\t\tmaybeEncryptedApplogs = encryptedApplogs\n\t} else {\n\t\tmaybeEncryptedApplogs = logsToPublish // publish nonEncrypted\n\t}\n\n\tDEBUG('adding all agent info and shareAtoms', {\n\t\tshare,\n\t\tagent,\n\t\tlogsToPublish,\n\t\t// threadToPublish, - very verbose\n\t\tagentSharedKeyLogs,\n\t})\n\tconst infoLogs = [\n\t\t...rollingFilter(lastWriteWins(appThread), { // TODO: use static filter for performance\n\t\t\ten: agent.ag,\n\t\t\tat: anyOf('agent/ecdh', 'agent/jwkd', 'agent/appAgent'),\n\t\t}).applogs,\n\t\t...(shareNameLog ? [shareNameLog] : []),\n\t\t...(shareCounterLog ? [shareCounterLog] : []),\n\t\t...agentSharedKeyLogs,\n\t]\n\tDEBUG(`[prepareSnapshotForPush] info logs:`, infoLogs)\n\tif (!infoLogs.find(({ at }) => at === 'agent/appAgent')) throw ERROR(`[prepareSnapshotForPush] appThread missing agent/appAgent log`)\n\n\tconst applogsToEncode = keepTruthy(maybeEncryptedApplogs)\n\tconst infologsToEncode = keepTruthy(infoLogs)\n\tif (!applogsToEncode.length) {\n\t\t// all applogs were filtered out as falsy — show raw→kept counts + a sample so we can see what came in\n\t\tthrow ERROR('no valid applogs', {\n\t\t\tagent: agent.did,\n\t\t\tprevSnapCID: prevSnapCID?.toString(),\n\t\t\tcounts: {\n\t\t\t\trawApplogs: maybeEncryptedApplogs.length,\n\t\t\t\tkeptApplogs: applogsToEncode.length,\n\t\t\t\trawInfo: infoLogs.length,\n\t\t\t\tkeptInfo: infologsToEncode.length,\n\t\t\t},\n\t\t\trawApplogsSample: applogsSummary(maybeEncryptedApplogs),\n\t\t})\n\t}\n\tif (!infologsToEncode.length) {\n\t\tthrow ERROR('no valid infologs', {\n\t\t\tagent: agent.did,\n\t\t\tprevSnapCID: prevSnapCID?.toString(),\n\t\t\tcounts: {\n\t\t\t\trawApplogs: maybeEncryptedApplogs.length,\n\t\t\t\tkeptApplogs: applogsToEncode.length,\n\t\t\t\trawInfo: infoLogs.length,\n\t\t\t\tkeptInfo: infologsToEncode.length,\n\t\t\t},\n\t\t\trawInfoSample: applogsSummary(infoLogs),\n\t\t})\n\t}\n\tconst encodedSnapshot = await encodeSnapshotAsCar(agent, applogsToEncode, infologsToEncode, prevSnapCID, prevCounter)\n\tDEBUG('inPrepareSnapshotForPush', { encodedSnapshot })\n\treturn encodedSnapshot\n}\n\n/**\n * @param applogs Encrypted or plain applogs\n * @returns Car file\n */\nexport async function encodeSnapshotAsCar(\n\tagent: AppAgent,\n\tapplogs: ApplogArrayNoCIDMaybeEncryptedRO,\n\tinfoLogs: readonly Applog[],\n\tprevSnapCID: CID | null,\n\tprevCounter: number | null,\n) {\n\tDEBUG(`[encodeSnapshotAsCar] encoding`, { agent, applogs, infoLogs })\n\tconst { cids: infoLogCids, encodedApplogs: encodedInfoLogs } = await encodeApplogsAsIPLD(infoLogs)\n\tconst { cids: applogCids, encodedApplogs } = await encodeApplogsAsIPLD(applogs)\n\tlet blocks = encodedApplogs.concat(encodedInfoLogs)\n\t// We need to wrap the array to get a CID\n\tconst infoLogsWrap = await encodeBlockOriginal({ logs: infoLogCids })\n\tblocks.push(infoLogsWrap)\n\tconst { rootCID: chunkRootCID, blocks: chunkBlocks } = await chunkApplogs(applogCids)\n\tblocks = blocks.concat(chunkBlocks) // (i) concat bc. https://stackoverflow.com/a/51860949\n\tconst infoSignature = await agent.sign(infoLogsWrap.cid.bytes)\n\tconst applogsSignature = await agent.sign(chunkRootCID.bytes)\n\tconst root = {\n\t\tinfo: infoLogsWrap.cid,\n\t\tapplogs: chunkRootCID,\n\t\tinfoSignature,\n\t\tapplogsSignature,\n\t\tprev: prevSnapCID,\n\t\tprevCounter: !prevSnapCID ? 0 : prevCounter !== null ? prevCounter + 1 : null,\n\t}\n\tDEBUG('[encodeSnapshotAsCar] encoding root', { root, logCids: applogCids, infoLogCids })\n\tconst encodedRoot = await encodeBlockOriginal(root)\n\tblocks.push(encodedRoot)\n\tDEBUG('[encodeSnapshotAsCar] => root', { encodedRoot })\n\n\treturn {\n\t\tcid: encodedRoot.cid,\n\t\tblob: await makeCarBlob(encodedRoot.cid, blocks), // TODO: create CarBuilder (incl .encodeAndAdd({...}))\n\t\tblocks,\n\t\tinfoLogCids,\n\t\tapplogCids,\n\t}\n}\n\n/** (i) IPFS has a block size limit of 1MB - which is about 15K CIDs */\nexport async function chunkApplogs(applogCids: CID<unknown, 297, 18, 1>[], size = 10000) {\n\tif (!applogCids.length) throw ERROR(`[chunkApplogs] called with empty array`)\n\tconst chunks = []\n\t// TODO: chunk by stable btree based on size or something like that\n\tfor (let i = 0; i < applogCids.length; i += size) {\n\t\tconst chunk = await encodeBlockOriginal({ logs: applogCids.slice(i, Math.min(i + applogCids.length, i + size)) })\n\t\tchunks.push(chunk)\n\t}\n\tif (chunks.length === 1) return { rootCID: chunks[0].cid, blocks: chunks }\n\tconst root = await encodeBlockOriginal({ chunks: chunks.map(chunk => chunk.cid) })\n\tconst blocks = [root, ...chunks]\n\tDEBUG(`[chunkApplogs] ${applogCids.length} logs chunked into ${chunks.length}`, { applogCids, root, blocks, chunks, dagJson })\n\treturn { rootCID: root.cid, blocks, chunks }\n}\nexport async function unchunkApplogsBlock(block: SnapBlockLogsOrChunks | null | undefined, blockStore: BlockStoreish): Promise<CID[]> {\n\tif (!block) return []\n\tif (isSnapBlockChunks(block)) {\n\t\treturn (await Promise.all(\n\t\t\tblock.chunks.map(async (chunkCid) => {\n\t\t\t\tconst block = (await getDecodedBlock(blockStore, chunkCid)) as SnapBlockLogs\n\t\t\t\tif (!block?.logs) throw ERROR(`Weird chunk`, block)\n\t\t\t\treturn block.logs\n\t\t\t}),\n\t\t)).flat()\n\t} else {\n\t\treturn block.logs ?? []\n\t}\n}\nexport function isSnapBlockChunks(block: SnapBlockLogsOrChunks | null | undefined): block is SnapBlockChunks {\n\treturn !!block && 'chunks' in block\n}\n/**\n * @param applogs Encrypted or plain applogs\n * @returns Car file\n */\nexport async function encodeSnapshotApplogsAsCar(\n\tapplogs: ApplogArrayMaybeEncryptedRO,\n) {\n\tconst encoded = await encodeApplogsAsIPLD(applogs)\n\tif (!encoded) throw ERROR('invalid applogs cannot continue', { encoded, applogs: applogsSummary(applogs) })\n\tconst { cids, encodedApplogs } = encoded\n\tconst root = { applogs: cids }\n\tconst encodedRoot = await encodeBlockOriginal(root)\n\tDEBUG('[encodeSnapshotApplogsAsCar] encoded root', { cids, encodedRoot })\n\n\treturn await makeCarBlob(encodedRoot.cid, [encodedRoot, ...encodedApplogs])\n}\n\nasync function encodeApplogsAsIPLD(applogs: ApplogArrayNoCIDMaybeEncryptedRO) {\n\tDEBUG({ applogs })\n\tconst validApplogs = applogs.filter(eachLog => !!eachLog)\n\tDEBUG({ validApplogs })\n\tif (!validApplogs.length) throw ERROR('no valid applogs')\n\tconst preppedLogs = validApplogs.map(log => prepareForPub(log as Applog).log)\n\tconst encodedApplogs = await Promise.all(preppedLogs.map(encodeBlockOriginal))\n\tDEBUG('[encodeApplogsAsIpld] encoded applogs', { preppedLogs, encodedApplogs })\n\n\tconst cids = encodedApplogs.map(b => {\n\t\tif (!b.cid) throw ERROR(`[publish] no cid for encoded log:`, b)\n\t\treturn b.cid\n\t})\n\treturn { cids, encodedApplogs }\n}\n","import { CarReader, CarWriter } from '@ipld/car'\nimport * as dagJson from '@ipld/dag-json'\nimport { Logger } from 'besonders-logger'\nimport { BlockView, CID } from 'multiformats'\nimport { sortApplogsByTs } from '../applog/applog-utils.ts'\nimport { Applog, ApplogArrayMaybeEncrypted, CidString } from '../applog/datom-types.ts'\nimport { unchunkApplogsBlock } from '../pubsub/snap-push.ts'\nimport { SnapBlockLogs, SnapBlockLogsOrChunks, SnapRootBlock } from '../pubsub/pubsub-types.ts'\nimport { areCidsEqual, containsCid } from './ipfs-utils.ts'\n\nconst { WARN, LOG, DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.INFO) // eslint-disable-line no-unused-vars\n\nexport type CIDForCar = CID // Exclude<Parameters<(typeof CarWriter)['create']>[0], void>\nexport type BlockForCar = Parameters<CarWriter['put']>[0]\n\nexport interface BlockStoreish {\n\tget(cid: CID): PromiseLike<Uint8Array> // (i) not using decoded version to be similar to blockstore-idb\n}\n\nexport interface DecodedCar {\n\trootCID: CID\n\t// blocks: Map<CidString, any>\n\tblockStore: BlockStoreish\n}\n\n/** Warning: unsorted & maybe encrypted */\nexport async function decodePubFromCar(car: CarReader) {\n\tconst decoded = await getBlocksOfCar(car)\n\treturn await decodePubFromBlocks(decoded)\n}\n\nexport async function decodePubFromBlocks(\n\t{ rootCID, blockStore }: DecodedCar,\n\t_recursionTrace: CID[] = [], // DEPRECATED: kept for API compat, unused in iterative version\n\tstopAtCID?: CID // NEW: stop iteration when we hit this CID\n) {\n\tif (!rootCID || !blockStore) {\n\t\tthrow ERROR('Empty roots/blocks', { rootCID, blockStore })\n\t}\n\n\tlet allApplogs: ApplogArrayMaybeEncrypted = []\n\tlet firstInfo: { logs: CID[] } | null = null\n\tlet currentCID: CID | undefined = rootCID\n\tconst visited = new Set<string>() // Loop detection (replaces recursionTrace)\n\tlet applogsCID: CID | null = null // From first snapshot only\n\n\twhile (currentCID) {\n\t\tconst cidStr = currentCID.toString()\n\n\t\t// Loop detection\n\t\tif (visited.has(cidStr)) {\n\t\t\tthrow ERROR('[decodePubFromBlocks] pub chain has a loop', {\n\t\t\t\tcurrentCID: cidStr,\n\t\t\t\tvisited: [...visited]\n\t\t\t})\n\t\t}\n\t\tvisited.add(cidStr)\n\n\t\t// Decode current snapshot\n\t\tconst root = (await getDecodedBlock(blockStore, currentCID)) as SnapRootBlock\n\t\tVERBOSE(`[decodePubFromBlocks] root:`, cidStr, root, { blockStore })\n\t\tif (!root) {\n\t\t\tthrow ERROR('[decodePubFromBlocks] root not found in blockStore', { blockStore, currentCID: cidStr })\n\t\t}\n\n\t\t// Decode applogs for this snapshot\n\t\tlet pubLogsArray: CID[]\n\t\tif (root?.info) {\n\t\t\t// New(er) format\n\t\t\tif (!applogsCID) applogsCID = root.applogs // Save from first snapshot\n\t\t\tconst applogsBlock = (await getDecodedBlock(blockStore, root.applogs)) as SnapBlockLogsOrChunks\n\t\t\tif (!applogsBlock) {\n\t\t\t\tthrow ERROR('[decodePubFromBlocks] applogs block missing from blockStore', {\n\t\t\t\t\tcid: root.applogs.toString(),\n\t\t\t\t\trootCID: cidStr,\n\t\t\t\t})\n\t\t\t}\n\t\t\tpubLogsArray = await unchunkApplogsBlock(applogsBlock, blockStore)\n\t\t\t// Info only from first (most recent) snapshot\n\t\t\tif (!firstInfo) {\n\t\t\t\tconst decoded = (await getDecodedBlock(blockStore, root.info)) as SnapBlockLogs\n\t\t\t\tif (decoded) {\n\t\t\t\t\tfirstInfo = decoded\n\t\t\t\t\tDEBUG(`new format - infoLogs`, firstInfo.logs.map(l => ({ [l.toString()]: l })))\n\t\t\t\t} else {\n\t\t\t\t\tWARN(`[decodePubFromBlocks] info block not found for ${root.info}, using empty info`)\n\t\t\t\t\tfirstInfo = { logs: [] }\n\t\t\t\t}\n\t\t\t}\n\t\t\t// TODO: verify signatures\n\t\t} else {\n\t\t\t// Old format\n\t\t\tpubLogsArray = root.applogs as any as CID[]\n\t\t}\n\n\t\tconst resolveLogFromCidLink = async (cidOrLink: CID) => {\n\t\t\tconst cid = cidOrLink\n\t\t\tconst applog = (await getDecodedBlock(blockStore, cid)) as Applog\n\t\t\tif (!applog) {\n\t\t\t\tERROR(`Could not find applog CID in pub blocks:`, cid.toString(), { cid, root, blockStore })\n\t\t\t\tthrow new Error(`Could not find applog CID in pub blocks: ${cid.toString()}`)\n\t\t\t}\n\t\t\tif ((applog.pv as any) instanceof CID) applog.pv = (applog.pv as any as CID).toV1().toString()\n\t\t\treturn {\n\t\t\t\t...applog,\n\t\t\t\tcid: cid.toV1().toString(),\n\t\t\t}\n\t\t}\n\n\t\tconst snapshotApplogs = await Promise.all(pubLogsArray.map(resolveLogFromCidLink))\n\t\tallApplogs = allApplogs.concat(snapshotApplogs)\n\n\t\t// Check if we should stop\n\t\tif (!root.prev) {\n\t\t\tbreak // End of chain\n\t\t}\n\t\tif (stopAtCID && areCidsEqual(root.prev, stopAtCID)) {\n\t\t\tDEBUG('[decodePubFromBlocks] stopping at stopAtCID:', stopAtCID.toString())\n\t\t\tbreak // Reached already-pulled snapshot\n\t\t}\n\n\t\t// Verify prev exists before continuing\n\t\tconst prevBytes = await blockStore.get(root.prev)\n\t\tif (!prevBytes) {\n\t\t\tthrow ERROR('[decodePubFromBlocks] prev snapshot missing from blockStore', {\n\t\t\t\tcurrentCID: cidStr,\n\t\t\t\tprev: root.prev.toString(),\n\t\t\t\tstopAtCID: stopAtCID?.toString(),\n\t\t\t\tvisited: [...visited]\n\t\t\t})\n\t\t}\n\n\t\tcurrentCID = root.prev // Move to previous snapshot\n\t}\n\n\tconst result = {\n\t\tcid: rootCID,\n\t\tinfo: firstInfo ? {\n\t\t\t...firstInfo,\n\t\t\tlogs: await Promise.all(firstInfo.logs.map(async (cidOrLink: CID) => {\n\t\t\t\tconst cid = cidOrLink\n\t\t\t\tconst applog = (await getDecodedBlock(blockStore, cid)) as Applog\n\t\t\t\tif (!applog) {\n\t\t\t\t\tERROR(`Could not find info log CID in pub blocks:`, cid.toString(), { cid, blockStore })\n\t\t\t\t\tthrow new Error(`Could not find info log CID in pub blocks: ${cid.toString()}`)\n\t\t\t\t}\n\t\t\t\tif ((applog.pv as any) instanceof CID) applog.pv = (applog.pv as any as CID).toV1().toString()\n\t\t\t\treturn {\n\t\t\t\t\t...applog,\n\t\t\t\t\tcid: cid.toV1().toString(),\n\t\t\t\t}\n\t\t\t})),\n\t\t} : null,\n\t\tapplogsCID,\n\t\tapplogs: allApplogs,\n\t}\n\tDEBUG('[decodePubFromBlocks] result:', result, { rootCID: rootCID.toString(), blockStore, applogs: allApplogs })\n\treturn result\n}\n\nexport async function getBlocksOfCar(car: CarReader) {\n\tconst rootsFromCar = await car.getRoots()\n\tconst roots = rootsFromCar.map(c => ((typeof c.toV1 === 'function') ? c : CID.decode(c.bytes)).toV1().toString() as CidString) // HACK\n\tconst blocks = new Map<CidString, any>()\n\tfor await (const { cid: cidFromCarblocks, bytes } of car.blocks()) {\n\t\tconst cid = (typeof cidFromCarblocks.toV1 === 'function') ? cidFromCarblocks : CID.decode(cidFromCarblocks.bytes)\n\t\tVERBOSE({ cidFromCarblocks, cid })\n\t\t// blocks.set(cid.toV1().toString(), dagJson.decode(bytes)) // HACK: tried using CID as map key, but because it's based on referential equality it's not working\n\t\tblocks.set(cid.toV1().toString(), bytes) // HACK: tried using CID as map key, but because it's based on referential equality it's not working\n\t}\n\tif (roots.length !== 1) {\n\t\tWARN('Unexpected roots count:', roots)\n\t}\n\treturn {\n\t\trootCID: CID.parse(roots[0]),\n\t\tblockStore: {\n\t\t\tget: (cid) => blocks.get(cid.toV1().toString()),\n\t\t},\n\t} satisfies DecodedCar\n}\nexport async function getDecodedBlock(blockStore: BlockStoreish, cid: CID) {\n\ttry {\n\t\tvar blob = await blockStore.get(cid)\n\t\tif (!blob) {\n\t\t\tWARN('returning null')\n\t\t\treturn null // I don't think this ever happens actually\n\t\t}\n\t} catch (err) {\n\t\tif ((err as any).message === 'Not Found') return null\n\t\tthrow err\n\t}\n\treturn dagJson.decode(blob)\n}\n\n// make out in the car... been a while but also sounds nice\nexport async function makeCarOut(roots: CIDForCar, blocks: BlockForCar[]) {\n\tconst { writer, out } = CarWriter.create(Array.isArray(roots) ? roots : [roots])\n\n\t// add the blocks to the CAR and close it\n\tVERBOSE(`Writing ${blocks.length} blocks to CAR`, { roots, blocks })\n\tblocks.forEach(b => writer.put(b))\n\twriter.close()\n\t// VERBOSE(`Wrote ${blocks.length} blocks to CAR`, writer)\n\treturn out\n} /** create a new CarWriter, with the encoded block as the root */\n\n// export async function makeCarReader(roots: CIDForCar, blocks: BlockForCar[]) {\n// \tconst out = await makeCarOut(roots, blocks)\n\n// \t// create a new CarReader we can hand to web3.storage.putCar\n// \tconst reader = await CarReader.fromIterable(out)\n// \tVERBOSE(`CAR reader`, reader)\n// \treturn reader\n// } /** create a new CarWriter, with the encoded block as the root */\n\nexport async function makeCarBlob(roots: CIDForCar, blocks: BlockForCar[]) {\n\tconst carOut = await makeCarOut(roots, blocks)\n\tconst chunks = []\n\tfor await (const chunk of carOut) {\n\t\tchunks.push(chunk)\n\t}\n\tconst blob = new Blob(chunks)\n\treturn blob\n}\nexport async function carFromBlob(blob: Blob | File): Promise<CarReader> {\n\treturn CarReader.fromBytes(new Uint8Array(await blob.arrayBuffer()))\n}\n\nfunction extractCids(value: unknown): CID[] {\n\tif (value instanceof CID) return [value]\n\tif (Array.isArray(value)) return value.flatMap(extractCids)\n\tif (value && typeof value === 'object') return Object.values(value).flatMap(extractCids)\n\treturn []\n}\n\nconst MAX_COLLECT_BLOCKS = 1_000_000\n\nexport async function collectDagBlocks(\n\tstartCID: CID,\n\tblockStore: BlockStoreish,\n): Promise<BlockForCar[]> {\n\tconst visited = new Set<string>()\n\tconst blocks: BlockForCar[] = []\n\tconst queue: CID[] = [startCID]\n\n\twhile (queue.length > 0) {\n\t\tif (blocks.length >= MAX_COLLECT_BLOCKS) {\n\t\t\tWARN(`[collectDagBlocks] hit ${MAX_COLLECT_BLOCKS} block limit, returning partial result`)\n\t\t\tbreak\n\t\t}\n\n\t\tconst cid = queue.shift()!\n\t\tconst cidStr = cid.toString()\n\t\tif (visited.has(cidStr)) continue\n\t\tvisited.add(cidStr)\n\n\t\tlet bytes: Uint8Array\n\t\ttry {\n\t\t\tbytes = await blockStore.get(cid)\n\t\t} catch {\n\t\t\tWARN(`[collectDagBlocks] block not found: ${cidStr}, stopping this branch`)\n\t\t\tcontinue\n\t\t}\n\t\tif (!bytes) {\n\t\t\tWARN(`[collectDagBlocks] block not found: ${cidStr}, stopping this branch`)\n\t\t\tcontinue\n\t\t}\n\n\t\tblocks.push({ cid, bytes })\n\n\t\tif (blocks.length % 1000 === 0) {\n\t\t\tLOG(`[collectDagBlocks] collected ${blocks.length} blocks...`)\n\t\t}\n\n\t\ttry {\n\t\t\tconst decoded = dagJson.decode(bytes)\n\t\t\tconst childCids = extractCids(decoded)\n\t\t\tfor (const child of childCids) {\n\t\t\t\tif (!visited.has(child.toString())) {\n\t\t\t\t\tqueue.push(child)\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Not dag-json — leaf block, no children to walk\n\t\t}\n\t}\n\n\tDEBUG(`[collectDagBlocks] collected ${blocks.length} blocks from ${startCID.toString()}`)\n\treturn blocks\n}\n\nexport function streamReaderToIterable(bodyReader: ReadableStreamDefaultReader<Uint8Array>): AsyncIterable<Uint8Array> {\n\treturn (async function*() {\n\t\twhile (true) {\n\t\t\tconst { done, value } = await bodyReader.read()\n\t\t\tVERBOSE(`[car] chunk`, { done, value })\n\t\t\tif (done) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tyield value\n\t\t}\n\t})()\n}\n"],"mappings":"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","names":["dagJson","Logger","WARN","LOG","DEBUG","VERBOSE","ERROR","Logger","share","dagJson","block"]}
|
|
@@ -11,7 +11,76 @@ import { isBefore } from "date-fns";
|
|
|
11
11
|
import { partial, pick } from "lodash-es";
|
|
12
12
|
import { isEqual } from "lodash-es";
|
|
13
13
|
import stringify from "safe-stable-stringify";
|
|
14
|
+
|
|
15
|
+
// src/applog/datom-types.ts
|
|
16
|
+
import { FormatRegistry, Type } from "@sinclair/typebox";
|
|
17
|
+
import { TypeCompiler } from "@sinclair/typebox/compiler";
|
|
18
|
+
var Nullable = (schema) => Type.Union([schema, Type.Null()]);
|
|
19
|
+
var EntityID_LENGTH = 7;
|
|
20
|
+
var isCID = /^(k51qz|baguq)[0-9a-z]{56,57}$/;
|
|
21
|
+
var isShortHash = /^[0-9A-Fa-f]{7,8}$/g;
|
|
22
|
+
FormatRegistry.Set("EntityID", (value) => !!value.match(isShortHash) || !!value.match(isCID));
|
|
23
|
+
var EntityID = Type.String();
|
|
24
|
+
var isEncryptedApplog = (l) => l?.enc instanceof Uint8Array;
|
|
25
|
+
FormatRegistry.Set("CID", (value) => !!value.match(isCID));
|
|
26
|
+
var CIDTB = Type.String({ pattern: isCID.source });
|
|
27
|
+
var isURL = /^http([s]?):\/\/.*\..*/;
|
|
28
|
+
FormatRegistry.Set("URL", (value) => !!value.match(isURL));
|
|
29
|
+
var URL = Type.String({ pattern: isURL.source });
|
|
30
|
+
var JsonValueTB = Type.Recursive(
|
|
31
|
+
(This) => Type.Union([
|
|
32
|
+
Type.String(),
|
|
33
|
+
Type.Number(),
|
|
34
|
+
Type.Boolean(),
|
|
35
|
+
Type.Null(),
|
|
36
|
+
Type.Array(This),
|
|
37
|
+
Type.Record(Type.String(), This)
|
|
38
|
+
])
|
|
39
|
+
);
|
|
40
|
+
var AppLogNoCidTB = Type.Object({
|
|
41
|
+
en: EntityID,
|
|
42
|
+
// EntityID
|
|
43
|
+
at: Type.String(),
|
|
44
|
+
// Attribute
|
|
45
|
+
vl: JsonValueTB,
|
|
46
|
+
// ApplogValue (JSON-serializable: primitives, arrays, objects)
|
|
47
|
+
ts: Type.String(),
|
|
48
|
+
// Timestamp
|
|
49
|
+
ag: Type.String(),
|
|
50
|
+
// AgentHash
|
|
51
|
+
pv: Nullable(CIDTB)
|
|
52
|
+
// CidString
|
|
53
|
+
});
|
|
54
|
+
var AppLogNoCidTBC = TypeCompiler.Compile(AppLogNoCidTB);
|
|
55
|
+
var getApplogNoCidTypeErrors = (obj) => Array.from(AppLogNoCidTBC.Errors(obj));
|
|
56
|
+
var isValidApplogNoCid = AppLogNoCidTBC.Check.bind(AppLogNoCidTBC);
|
|
57
|
+
var AppLogTB = Type.Composite([
|
|
58
|
+
Type.Object({
|
|
59
|
+
cid: CIDTB
|
|
60
|
+
}),
|
|
61
|
+
AppLogNoCidTB
|
|
62
|
+
]);
|
|
63
|
+
var AppLogTBC = TypeCompiler.Compile(AppLogTB);
|
|
64
|
+
var getApplogTypeErrors = (obj) => Array.from(AppLogTBC.Errors(obj));
|
|
65
|
+
var isValidApplog = AppLogTBC.Check.bind(AppLogTBC);
|
|
66
|
+
|
|
67
|
+
// src/applog/applog-utils.ts
|
|
14
68
|
var { WARN, LOG, DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.INFO);
|
|
69
|
+
var applogSummary = (log) => {
|
|
70
|
+
if (!log) return "\u2205";
|
|
71
|
+
const a = log;
|
|
72
|
+
const cid = a.cid ? `#${String(a.cid).slice(-6)}` : "";
|
|
73
|
+
if (isEncryptedApplog(log)) return `enc[${log.enc.length}B]${cid}`;
|
|
74
|
+
const vl = a.vl === void 0 ? "\u2205" : JSON.stringify(a.vl) ?? String(a.vl);
|
|
75
|
+
const vlStr = vl.length > 32 ? `${vl.slice(0, 32)}\u2026` : vl;
|
|
76
|
+
return `${a.en}/${a.at}=${vlStr}${a.ts ? `@${a.ts}` : ""}${cid}`;
|
|
77
|
+
};
|
|
78
|
+
var applogsSummary = (logs, sample = 3) => {
|
|
79
|
+
if (!logs) return "\u2205";
|
|
80
|
+
if (!logs.length) return "[0]";
|
|
81
|
+
const shown = logs.slice(0, sample).map(applogSummary).join(", ");
|
|
82
|
+
return `[${logs.length}] ${shown}${logs.length > sample ? ` \u2026+${logs.length - sample}` : ""}`;
|
|
83
|
+
};
|
|
15
84
|
var isoDateStrCompare = (strA, strB, dir = "asc") => dir === "asc" ? strA.localeCompare(strB, "en-US") : strB.localeCompare(strA, "en-US");
|
|
16
85
|
var objEqualByKeys = (keys, objA, objB) => {
|
|
17
86
|
return isEqual(pick(objA, keys), pick(objB, keys));
|
|
@@ -100,7 +169,9 @@ function topoSortByPv(logs, dir) {
|
|
|
100
169
|
visited.add(log.cid);
|
|
101
170
|
result.push(log);
|
|
102
171
|
const children = childrenByPv.get(log.cid);
|
|
103
|
-
if (children)
|
|
172
|
+
if (children) {
|
|
173
|
+
for (let i = children.length - 1; i >= 0; i--) stack.push(children[i]);
|
|
174
|
+
}
|
|
104
175
|
}
|
|
105
176
|
if (result.length < logs.length) {
|
|
106
177
|
for (const log of logs) if (!visited.has(log.cid)) result.push(log);
|
|
@@ -560,6 +631,16 @@ var Thread = class {
|
|
|
560
631
|
_subscribers = [];
|
|
561
632
|
/** Monotonic counter incremented on every mutation. Used by memoizedFn to invalidate caches. */
|
|
562
633
|
_version = 0;
|
|
634
|
+
/**
|
|
635
|
+
* Memoized cid→membership lookups, rebuilt lazily on first read after a mutation.
|
|
636
|
+
* Previously these getters rebuilt a fresh Set/Map on EVERY access, which turned a
|
|
637
|
+
* bulk `insertMissing(N)` (N × hasApplog over a thread of M) into O(N·M) — pegging a
|
|
638
|
+
* core for tens of minutes on ~90k-applog threads. Now the collection is built once
|
|
639
|
+
* per mutation batch and reused across the whole filter loop. Invalidated in
|
|
640
|
+
* {@link invalidateApplogCaches}, called from every `_applogs` mutation path.
|
|
641
|
+
*/
|
|
642
|
+
_cidSet = null;
|
|
643
|
+
_byCid = null;
|
|
563
644
|
get readOnly() {
|
|
564
645
|
if (this.parents.length !== 1) return true;
|
|
565
646
|
return this.parents[0].readOnly;
|
|
@@ -584,9 +665,23 @@ var Thread = class {
|
|
|
584
665
|
if (idx >= 0) list.splice(idx, 1);
|
|
585
666
|
};
|
|
586
667
|
}
|
|
668
|
+
/**
|
|
669
|
+
* Drop memoized cid lookups. MUST be called from every path that mutates `_applogs`
|
|
670
|
+
* (or reassigns it). {@link notifySubscribers} covers the notify-emitting mutations
|
|
671
|
+
* (insertRaw, MappedThread remap/parent-update); non-notifying mutations (e.g.
|
|
672
|
+
* {@link WriteableThread.purge}) must call this explicitly.
|
|
673
|
+
*/
|
|
674
|
+
invalidateApplogCaches() {
|
|
675
|
+
this._cidSet = null;
|
|
676
|
+
this._byCid = null;
|
|
677
|
+
}
|
|
587
678
|
notifySubscribers(event) {
|
|
588
679
|
this._version++;
|
|
589
|
-
|
|
680
|
+
this.invalidateApplogCaches();
|
|
681
|
+
DEBUG2(`[thread: ${this.name}] notifying`, this._derivedSubscribers.length, "derived +", this._subscribers.length, "subscribers of", {
|
|
682
|
+
...event,
|
|
683
|
+
subs: this._subscribers
|
|
684
|
+
});
|
|
590
685
|
const derived = [...this._derivedSubscribers];
|
|
591
686
|
for (const subscriber of derived) {
|
|
592
687
|
subscriber(event);
|
|
@@ -611,7 +706,10 @@ var Thread = class {
|
|
|
611
706
|
return this._applogs.map((l) => l.cid);
|
|
612
707
|
}
|
|
613
708
|
get applogsCidSet() {
|
|
614
|
-
|
|
709
|
+
if (this._cidSet === null) {
|
|
710
|
+
this._cidSet = new Set(this._applogs.map((l) => l.cid));
|
|
711
|
+
}
|
|
712
|
+
return this._cidSet;
|
|
615
713
|
}
|
|
616
714
|
map(fn) {
|
|
617
715
|
return this.applogs.map(fn);
|
|
@@ -640,7 +738,10 @@ var Thread = class {
|
|
|
640
738
|
return this.applogsCidSet.has(cid.toString());
|
|
641
739
|
}
|
|
642
740
|
get applogsByCid() {
|
|
643
|
-
|
|
741
|
+
if (this._byCid === null) {
|
|
742
|
+
this._byCid = new Map(this._applogs.map((log) => [log.cid, log]));
|
|
743
|
+
}
|
|
744
|
+
return this._byCid;
|
|
644
745
|
}
|
|
645
746
|
getApplog(cid) {
|
|
646
747
|
return this.applogsByCid.get(cid.toString());
|
|
@@ -676,6 +777,17 @@ var Thread = class {
|
|
|
676
777
|
get hasParents() {
|
|
677
778
|
return !!this.parents?.length;
|
|
678
779
|
}
|
|
780
|
+
// Compact representation for server-side / plain console logging (Node's util.inspect).
|
|
781
|
+
// ⚠ Only consulted by Node — browser devtools ignore this symbol and keep rendering the
|
|
782
|
+
// live, expandable object, so passing `thread` to a logger stays clickable in devtools
|
|
783
|
+
// while no longer splatting every applog + the whole parent chain + subscribers to stdout.
|
|
784
|
+
[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
|
|
785
|
+
try {
|
|
786
|
+
return `${this.constructor.name}<${this.nameAndSizeUntracked}${this.filters?.length ? ` |${this.filters.join(",")}` : ""}>`;
|
|
787
|
+
} catch {
|
|
788
|
+
return `${this.constructor.name}<${this.name} (size?)>`;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
679
791
|
};
|
|
680
792
|
var getLogsFromThread = (logsOrThread) => logsOrThread instanceof Thread ? logsOrThread.applogs : logsOrThread;
|
|
681
793
|
var StaticThread = class _StaticThread extends Thread {
|
|
@@ -703,60 +815,6 @@ import { sha256 } from "@noble/hashes/sha2.js";
|
|
|
703
815
|
import { Logger as Logger3 } from "besonders-logger";
|
|
704
816
|
import { CID, digest as Digest } from "multiformats";
|
|
705
817
|
import { encode as multiformatsEncode } from "multiformats/block";
|
|
706
|
-
|
|
707
|
-
// src/applog/datom-types.ts
|
|
708
|
-
import { FormatRegistry, Type } from "@sinclair/typebox";
|
|
709
|
-
import { TypeCompiler } from "@sinclair/typebox/compiler";
|
|
710
|
-
var Nullable = (schema) => Type.Union([schema, Type.Null()]);
|
|
711
|
-
var EntityID_LENGTH = 7;
|
|
712
|
-
var isCID = /^(k51qz|baguq)[0-9a-z]{56,57}$/;
|
|
713
|
-
var isShortHash = /^[0-9A-Fa-f]{7,8}$/g;
|
|
714
|
-
FormatRegistry.Set("EntityID", (value) => !!value.match(isShortHash) || !!value.match(isCID));
|
|
715
|
-
var EntityID = Type.String();
|
|
716
|
-
var isEncryptedApplog = (l) => l?.enc instanceof Uint8Array;
|
|
717
|
-
FormatRegistry.Set("CID", (value) => !!value.match(isCID));
|
|
718
|
-
var CIDTB = Type.String({ pattern: isCID.source });
|
|
719
|
-
var isURL = /^http([s]?):\/\/.*\..*/;
|
|
720
|
-
FormatRegistry.Set("URL", (value) => !!value.match(isURL));
|
|
721
|
-
var URL = Type.String({ pattern: isURL.source });
|
|
722
|
-
var JsonValueTB = Type.Recursive(
|
|
723
|
-
(This) => Type.Union([
|
|
724
|
-
Type.String(),
|
|
725
|
-
Type.Number(),
|
|
726
|
-
Type.Boolean(),
|
|
727
|
-
Type.Null(),
|
|
728
|
-
Type.Array(This),
|
|
729
|
-
Type.Record(Type.String(), This)
|
|
730
|
-
])
|
|
731
|
-
);
|
|
732
|
-
var AppLogNoCidTB = Type.Object({
|
|
733
|
-
en: EntityID,
|
|
734
|
-
// EntityID
|
|
735
|
-
at: Type.String(),
|
|
736
|
-
// Attribute
|
|
737
|
-
vl: JsonValueTB,
|
|
738
|
-
// ApplogValue (JSON-serializable: primitives, arrays, objects)
|
|
739
|
-
ts: Type.String(),
|
|
740
|
-
// Timestamp
|
|
741
|
-
ag: Type.String(),
|
|
742
|
-
// AgentHash
|
|
743
|
-
pv: Nullable(CIDTB)
|
|
744
|
-
// CidString
|
|
745
|
-
});
|
|
746
|
-
var AppLogNoCidTBC = TypeCompiler.Compile(AppLogNoCidTB);
|
|
747
|
-
var getApplogNoCidTypeErrors = (obj) => Array.from(AppLogNoCidTBC.Errors(obj));
|
|
748
|
-
var isValidApplogNoCid = AppLogNoCidTBC.Check.bind(AppLogNoCidTBC);
|
|
749
|
-
var AppLogTB = Type.Composite([
|
|
750
|
-
Type.Object({
|
|
751
|
-
cid: CIDTB
|
|
752
|
-
}),
|
|
753
|
-
AppLogNoCidTB
|
|
754
|
-
]);
|
|
755
|
-
var AppLogTBC = TypeCompiler.Compile(AppLogTB);
|
|
756
|
-
var getApplogTypeErrors = (obj) => Array.from(AppLogTBC.Errors(obj));
|
|
757
|
-
var isValidApplog = AppLogTBC.Check.bind(AppLogTBC);
|
|
758
|
-
|
|
759
|
-
// src/ipfs/ipfs-utils.ts
|
|
760
818
|
import { base36 } from "multiformats/bases/base36";
|
|
761
819
|
import { sha256 as sha265Hasher } from "multiformats/hashes/sha2";
|
|
762
820
|
var { WARN: WARN3, LOG: LOG3, DEBUG: DEBUG3, VERBOSE: VERBOSE3, ERROR: ERROR3 } = Logger3.setup(Logger3.INFO);
|
|
@@ -1069,6 +1127,7 @@ function refCountedMemoizedFn(name, fn, opts) {
|
|
|
1069
1127
|
import { Logger as Logger5 } from "besonders-logger";
|
|
1070
1128
|
import { sortedIndexBy } from "lodash-es";
|
|
1071
1129
|
var { WARN: WARN5, LOG: LOG5, DEBUG: DEBUG5, VERBOSE: VERBOSE5, ERROR: ERROR5 } = Logger5.setup(Logger5.INFO);
|
|
1130
|
+
var threadEventSummary = (e) => isInitEvent(e) ? `init ${applogsSummary(e.init)}` : `added ${applogsSummary(e.added)}${e.removed ? ` removed ${applogsSummary(e.removed)}` : ""}`;
|
|
1072
1131
|
var MappedThread = class _MappedThread extends Thread {
|
|
1073
1132
|
// mapped to unsubscribe function
|
|
1074
1133
|
constructor(name, parents, filters, _derivation, _writeMapper = null, _readOnly) {
|
|
@@ -1215,9 +1274,10 @@ var MappedThread = class _MappedThread extends Thread {
|
|
|
1215
1274
|
this._applogs.splice(idx, 1);
|
|
1216
1275
|
} else {
|
|
1217
1276
|
throw ERROR5(`MappedThread{${this.name}} toRemove: log not found`, toRemove, {
|
|
1218
|
-
thread: this,
|
|
1219
|
-
|
|
1220
|
-
|
|
1277
|
+
thread: this.nameAndSizeUntracked,
|
|
1278
|
+
currentLogs: applogsSummary(this._applogs),
|
|
1279
|
+
event: threadEventSummary(event),
|
|
1280
|
+
result: threadEventSummary(result)
|
|
1221
1281
|
});
|
|
1222
1282
|
}
|
|
1223
1283
|
}
|
|
@@ -1228,6 +1288,17 @@ var MappedThread = class _MappedThread extends Thread {
|
|
|
1228
1288
|
get readOnly() {
|
|
1229
1289
|
return this._readOnly ?? false;
|
|
1230
1290
|
}
|
|
1291
|
+
// A no-derivation MappedThread SHARES its parent's `_applogs` array (see constructor) and never
|
|
1292
|
+
// mutates it itself — the parent does, and the parent invalidates only its own cid caches. So a
|
|
1293
|
+
// local cache here would go stale after a parent insert. Delegate membership lookups to the parent
|
|
1294
|
+
// (chaining up to the array's real owner), whose cache is always fresh. Derived threads own their
|
|
1295
|
+
// array and use the inherited, self-invalidating cache.
|
|
1296
|
+
get applogsCidSet() {
|
|
1297
|
+
return this._derivation ? super.applogsCidSet : this.parents[0].applogsCidSet;
|
|
1298
|
+
}
|
|
1299
|
+
get applogsByCid() {
|
|
1300
|
+
return this._derivation ? super.applogsByCid : this.parents[0].applogsByCid;
|
|
1301
|
+
}
|
|
1231
1302
|
};
|
|
1232
1303
|
|
|
1233
1304
|
// src/thread/filters.ts
|
|
@@ -1591,6 +1662,7 @@ var WriteableThread = class extends Thread {
|
|
|
1591
1662
|
purge(cidsToPurge) {
|
|
1592
1663
|
const beforeCount = this.applogs.length;
|
|
1593
1664
|
this._applogs = this.applogs.filter((log) => !cidsToPurge.includes(log.cid));
|
|
1665
|
+
this.invalidateApplogCaches();
|
|
1594
1666
|
return beforeCount - this.applogs.length;
|
|
1595
1667
|
}
|
|
1596
1668
|
insert(appLogsToInsert) {
|
|
@@ -1736,7 +1808,7 @@ function debounceWrites(thread, wait = 700, removeDuplicatesWith = compareApplog
|
|
|
1736
1808
|
if (thread.readOnly) throw ERROR9(`[debounceWrites] but readOnly thread`, thread.name);
|
|
1737
1809
|
let insertQueue = [];
|
|
1738
1810
|
const debouncedCommit = debounce(() => {
|
|
1739
|
-
|
|
1811
|
+
DEBUG9(`Debounce tail`, { thread: thread.nameAndSizeUntracked, queued: applogsSummary(insertQueue) });
|
|
1740
1812
|
const toInsert = ensureTsPvAndFinalizeApplogs(
|
|
1741
1813
|
// ? uniq, sure - but which one is used? (update: seems the first one, so reverse)
|
|
1742
1814
|
uniqWith(insertQueue.reverse(), removeDuplicatesWith),
|
|
@@ -1746,7 +1818,7 @@ function debounceWrites(thread, wait = 700, removeDuplicatesWith = compareApplog
|
|
|
1746
1818
|
insertQueue.splice(0, insertQueue.length);
|
|
1747
1819
|
}, wait);
|
|
1748
1820
|
const handleInsert = (applogs) => {
|
|
1749
|
-
DEBUG9(`Debounce input:`, applogs, { thread
|
|
1821
|
+
DEBUG9(`Debounce input:`, applogsSummary(applogs), { thread: thread.nameAndSizeUntracked, queued: insertQueue.length });
|
|
1750
1822
|
insertQueue.push(...applogs);
|
|
1751
1823
|
debouncedCommit();
|
|
1752
1824
|
return null;
|
|
@@ -1843,6 +1915,8 @@ export {
|
|
|
1843
1915
|
ensureValidCIDinstance,
|
|
1844
1916
|
areCidsEqual,
|
|
1845
1917
|
containsCid,
|
|
1918
|
+
applogSummary,
|
|
1919
|
+
applogsSummary,
|
|
1846
1920
|
isoDateStrCompare,
|
|
1847
1921
|
objEqualByKeys,
|
|
1848
1922
|
valueEq,
|
|
@@ -1919,4 +1993,4 @@ export {
|
|
|
1919
1993
|
withPvFrom,
|
|
1920
1994
|
joinThreads
|
|
1921
1995
|
};
|
|
1922
|
-
//# sourceMappingURL=chunk-
|
|
1996
|
+
//# sourceMappingURL=chunk-OUQE6LG4.js.map
|