@wovin/core 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/applog/applog-utils.d.ts +15 -0
- package/dist/applog/applog-utils.d.ts.map +1 -1
- package/dist/applog/datom-types.d.ts +63 -7
- package/dist/applog/datom-types.d.ts.map +1 -1
- package/dist/applog.js +7 -1
- package/dist/blockstore.js +2 -0
- package/dist/blockstore.js.map +1 -1
- package/dist/{chunk-L5EEEGE6.js → chunk-2OXLPZQI.js} +747 -679
- package/dist/chunk-2OXLPZQI.js.map +1 -0
- package/dist/{chunk-QZXKQCAY.js → chunk-2PJFLZRC.js} +7 -2
- package/dist/{chunk-QZXKQCAY.js.map → chunk-2PJFLZRC.js.map} +1 -1
- package/dist/chunk-64EJIJAJ.js +17 -0
- package/dist/chunk-64EJIJAJ.js.map +1 -0
- package/dist/chunk-7QEGHKR4.js +17 -0
- package/dist/chunk-7QEGHKR4.js.map +1 -0
- package/dist/{chunk-PD3C7XUM.js → chunk-EHO2BFFY.js} +2 -2
- package/dist/chunk-ICBK7NC4.js +27 -0
- package/dist/chunk-ICBK7NC4.js.map +1 -0
- package/dist/{chunk-CPSDKFBG.js → chunk-OKXRRWNS.js} +5 -14
- package/dist/chunk-OKXRRWNS.js.map +1 -0
- package/dist/{chunk-3WZVG277.js → chunk-Q4EMPWA3.js} +17 -9
- package/dist/chunk-Q4EMPWA3.js.map +1 -0
- package/dist/{chunk-J2FDHGOZ.js → chunk-VGIACGWX.js} +3 -3
- package/dist/{chunk-3JZMOEOD.js → chunk-WVW4YXB5.js} +2 -2
- package/dist/chunk-XF4DWOAE.js +25 -0
- package/dist/chunk-XF4DWOAE.js.map +1 -0
- package/dist/index.js +17 -9
- package/dist/ipfs/car.d.ts.map +1 -1
- package/dist/ipfs.js +4 -4
- package/dist/ipns/gateway-resolver.d.ts +21 -0
- package/dist/ipns/gateway-resolver.d.ts.map +1 -0
- package/dist/ipns/ipns-record.d.ts +28 -7
- package/dist/ipns/ipns-record.d.ts.map +1 -1
- package/dist/ipns/ipns-w3name.d.ts +15 -0
- package/dist/ipns/ipns-w3name.d.ts.map +1 -0
- package/dist/ipns/ipns-watcher.d.ts +190 -0
- package/dist/ipns/ipns-watcher.d.ts.map +1 -0
- package/dist/ipns.d.ts +3 -0
- package/dist/ipns.d.ts.map +1 -1
- package/dist/ipns.js +488 -8
- package/dist/ipns.js.map +1 -1
- package/dist/pubsub/snap-push.d.ts +2 -2
- package/dist/pubsub/snap-push.d.ts.map +1 -1
- package/dist/pubsub.js +4 -4
- package/dist/query/basic.d.ts +3 -3
- package/dist/query/basic.d.ts.map +1 -1
- package/dist/query/entity-collection.d.ts.map +1 -1
- package/dist/query/matchers.d.ts +12 -1
- package/dist/query/matchers.d.ts.map +1 -1
- package/dist/query.js +7 -5
- package/dist/retrieve.js +4 -4
- package/dist/thread/indexes.d.ts +3 -2
- package/dist/thread/indexes.d.ts.map +1 -1
- package/dist/thread.js +1 -1
- package/dist/viewmodel/adapters/arktype.d.ts +33 -0
- package/dist/viewmodel/adapters/arktype.d.ts.map +1 -0
- package/dist/viewmodel/adapters/arktype.js +7 -0
- package/dist/viewmodel/adapters/arktype.js.map +1 -0
- package/dist/viewmodel/adapters/typebox.d.ts +35 -0
- package/dist/viewmodel/adapters/typebox.d.ts.map +1 -0
- package/dist/viewmodel/adapters/typebox.js +7 -0
- package/dist/viewmodel/adapters/typebox.js.map +1 -0
- package/dist/viewmodel/adapters/typia.d.ts +40 -0
- package/dist/viewmodel/adapters/typia.d.ts.map +1 -0
- package/dist/viewmodel/adapters/typia.js +7 -0
- package/dist/viewmodel/adapters/typia.js.map +1 -0
- package/dist/viewmodel/adapters/zod.d.ts +30 -0
- package/dist/viewmodel/adapters/zod.d.ts.map +1 -0
- package/dist/viewmodel/adapters/zod.js +7 -0
- package/dist/viewmodel/adapters/zod.js.map +1 -0
- package/dist/viewmodel/builder.d.ts +40 -0
- package/dist/viewmodel/builder.d.ts.map +1 -0
- package/dist/viewmodel/examples/all-adapters.d.ts +26 -0
- package/dist/viewmodel/examples/all-adapters.d.ts.map +1 -0
- package/dist/viewmodel/factory.d.ts +38 -0
- package/dist/viewmodel/factory.d.ts.map +1 -0
- package/dist/viewmodel/index.d.ts +10 -0
- package/dist/viewmodel/index.d.ts.map +1 -0
- package/dist/viewmodel/index.js +313 -0
- package/dist/viewmodel/index.js.map +1 -0
- package/dist/viewmodel/schema-adapter.d.ts +16 -0
- package/dist/viewmodel/schema-adapter.d.ts.map +1 -0
- package/dist/viewmodel/types.d.ts +97 -0
- package/dist/viewmodel/types.d.ts.map +1 -0
- package/package.json +29 -3
- package/src/applog/applog-utils.ts +48 -4
- package/src/applog/datom-types.ts +24 -5
- package/src/applog/object-values.test.ts +106 -0
- package/src/ipfs/car.ts +8 -2
- package/src/ipns/gateway-resolver.ts +63 -0
- package/src/ipns/ipns-record.ts +68 -17
- package/src/ipns/ipns-w3name.ts +103 -0
- package/src/ipns/ipns-watcher.ts +607 -0
- package/src/ipns.ts +3 -0
- package/src/pubsub/snap-push.ts +8 -6
- package/src/query/entity-collection.ts +2 -1
- package/src/query/matchers.ts +23 -1
- package/src/thread/basic.ts +2 -2
- package/src/thread/indexes.ts +15 -9
- package/src/viewmodel/adapters/arktype.ts +44 -0
- package/src/viewmodel/adapters/typebox.ts +59 -0
- package/src/viewmodel/adapters/typia.ts +50 -0
- package/src/viewmodel/adapters/zod.ts +55 -0
- package/src/viewmodel/builder.ts +71 -0
- package/src/viewmodel/examples/all-adapters.ts +206 -0
- package/src/viewmodel/factory.ts +330 -0
- package/src/viewmodel/index.ts +22 -0
- package/src/viewmodel/schema-adapter.ts +27 -0
- package/src/viewmodel/types.ts +152 -0
- package/dist/chunk-3WZVG277.js.map +0 -1
- package/dist/chunk-CPSDKFBG.js.map +0 -1
- package/dist/chunk-L5EEEGE6.js.map +0 -1
- /package/dist/{chunk-PD3C7XUM.js.map → chunk-EHO2BFFY.js.map} +0 -0
- /package/dist/{chunk-J2FDHGOZ.js.map → chunk-VGIACGWX.js.map} +0 -0
- /package/dist/{chunk-3JZMOEOD.js.map → chunk-WVW4YXB5.js.map} +0 -0
|
@@ -3,15 +3,16 @@ import {
|
|
|
3
3
|
} from "./chunk-YDAKBU6Q.js";
|
|
4
4
|
import {
|
|
5
5
|
lastWriteWins
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2PJFLZRC.js";
|
|
7
7
|
import {
|
|
8
|
+
anyOf,
|
|
8
9
|
areCidsEqual,
|
|
9
10
|
encodeBlockOriginal,
|
|
10
11
|
ensureTsPvAndFinalizeApplog,
|
|
11
12
|
getLogsFromThread,
|
|
12
13
|
prepareForPub,
|
|
13
14
|
rollingFilter
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-2OXLPZQI.js";
|
|
15
16
|
|
|
16
17
|
// src/pubsub/snap-push.ts
|
|
17
18
|
import * as dagJson2 from "@ipld/dag-json";
|
|
@@ -57,8 +58,14 @@ async function decodePubFromBlocks({ rootCID, blockStore }, _recursionTrace = []
|
|
|
57
58
|
const applogsBlock = await getDecodedBlock(blockStore, root.applogs);
|
|
58
59
|
pubLogsArray = await unchunkApplogsBlock(applogsBlock, blockStore);
|
|
59
60
|
if (!firstInfo) {
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
const decoded = await getDecodedBlock(blockStore, root.info);
|
|
62
|
+
if (decoded) {
|
|
63
|
+
firstInfo = decoded;
|
|
64
|
+
DEBUG(`new format - infoLogs`, firstInfo.logs.map((l) => ({ [l.toString()]: l })));
|
|
65
|
+
} else {
|
|
66
|
+
WARN(`[decodePubFromBlocks] info block not found for ${root.info}, using empty info`);
|
|
67
|
+
firstInfo = { logs: [] };
|
|
68
|
+
}
|
|
62
69
|
}
|
|
63
70
|
} else {
|
|
64
71
|
pubLogsArray = root.applogs;
|
|
@@ -309,7 +316,7 @@ async function prepareSnapshotForPush(agent, appThread, threadToPublish, share,
|
|
|
309
316
|
...rollingFilter(lastWriteWins(appThread), {
|
|
310
317
|
// TODO: use static filter for performance
|
|
311
318
|
en: agent.ag,
|
|
312
|
-
at:
|
|
319
|
+
at: anyOf("agent/ecdh", "agent/jwkd", "agent/appAgent")
|
|
313
320
|
}).applogs,
|
|
314
321
|
...shareNameLog ? [shareNameLog] : [],
|
|
315
322
|
...shareCounterLog ? [shareCounterLog] : [],
|
|
@@ -375,20 +382,21 @@ async function chunkApplogs(applogCids, size = 1e4) {
|
|
|
375
382
|
return { rootCID: root.cid, blocks, chunks };
|
|
376
383
|
}
|
|
377
384
|
async function unchunkApplogsBlock(block, blockStore) {
|
|
385
|
+
if (!block) return [];
|
|
378
386
|
if (isSnapBlockChunks(block)) {
|
|
379
387
|
return (await Promise.all(
|
|
380
388
|
block.chunks.map(async (chunkCid) => {
|
|
381
389
|
const block2 = await getDecodedBlock(blockStore, chunkCid);
|
|
382
|
-
if (!block2
|
|
390
|
+
if (!block2?.logs) throw ERROR2(`Weird chunk`, block2);
|
|
383
391
|
return block2.logs;
|
|
384
392
|
})
|
|
385
393
|
)).flat();
|
|
386
394
|
} else {
|
|
387
|
-
return block.logs;
|
|
395
|
+
return block.logs ?? [];
|
|
388
396
|
}
|
|
389
397
|
}
|
|
390
398
|
function isSnapBlockChunks(block) {
|
|
391
|
-
return block
|
|
399
|
+
return !!block && "chunks" in block;
|
|
392
400
|
}
|
|
393
401
|
async function encodeSnapshotApplogsAsCar(applogs) {
|
|
394
402
|
const encoded = await encodeApplogsAsIPLD(applogs);
|
|
@@ -431,4 +439,4 @@ export {
|
|
|
431
439
|
collectDagBlocks,
|
|
432
440
|
streamReaderToIterable
|
|
433
441
|
};
|
|
434
|
-
//# sourceMappingURL=chunk-
|
|
442
|
+
//# sourceMappingURL=chunk-Q4EMPWA3.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 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\tthrow ERROR('no valid applogs', { agent, maybeEncryptedApplogs, infoLogs, applogsToEncode, infologsToEncode, prevSnapCID })\n\t}\n\tif (!infologsToEncode.length) {\n\t\tthrow ERROR('no valid infologs', { agent, maybeEncryptedApplogs, infoLogs, applogsToEncode, infologsToEncode, prevSnapCID })\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', { applogs, encoded })\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\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"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
unchunkApplogsBlock
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Q4EMPWA3.js";
|
|
4
4
|
import {
|
|
5
5
|
areCidsEqual,
|
|
6
6
|
removeDuplicateAppLogs
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-2OXLPZQI.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-VGIACGWX.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
areCidsEqual
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2OXLPZQI.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-WVW4YXB5.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/viewmodel/adapters/zod.ts
|
|
2
|
+
function createZodAdapter(zodSchema, entityPrefix, options) {
|
|
3
|
+
const shape = zodSchema.shape;
|
|
4
|
+
const toAtPath = options?.toAtPath ?? ((prefix, name) => `${prefix}/${name}`);
|
|
5
|
+
const attributeDefs = Object.entries(shape).map(([name, fieldSchema]) => {
|
|
6
|
+
const isOptional = fieldSchema.isOptional() || fieldSchema.isNullable();
|
|
7
|
+
const atPath = options?.atOverrides?.[name] ?? toAtPath(entityPrefix, name);
|
|
8
|
+
return {
|
|
9
|
+
name,
|
|
10
|
+
atPath,
|
|
11
|
+
optional: isOptional
|
|
12
|
+
};
|
|
13
|
+
});
|
|
14
|
+
return {
|
|
15
|
+
getAttributeDefs: () => attributeDefs,
|
|
16
|
+
getDefaults: () => options?.defaults ?? {},
|
|
17
|
+
getEntityPrefix: () => entityPrefix,
|
|
18
|
+
createValidator: () => (value) => zodSchema.safeParse(value).success
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
createZodAdapter
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=chunk-XF4DWOAE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/viewmodel/adapters/zod.ts"],"sourcesContent":["import type { ApplogValue } from '../../applog/datom-types.ts'\nimport type { ISchemaAdapter, VMAttributeDef } from '../types.ts'\nimport type { ZodObject, ZodType, ZodTypeAny } from 'zod'\n\n/**\n * Create a schema adapter from a Zod object schema.\n *\n * Usage:\n * ```ts\n * import { z } from 'zod'\n * import { createZodAdapter } from '@wovin/core/viewmodel/adapters/zod'\n *\n * const MySchema = z.object({\n * name: z.string(),\n * age: z.number().optional(),\n * })\n *\n * const adapter = createZodAdapter(MySchema, 'myEntity')\n * ```\n *\n * The type parameter `T` is the inferred type of the schema.\n */\nexport function createZodAdapter<T extends Record<string, ApplogValue> = Record<string, ApplogValue>>(\n\tzodSchema: ZodObject<Record<string, ZodTypeAny>>,\n\tentityPrefix: string,\n\toptions?: {\n\t\t/** Override at-paths for specific attributes */\n\t\tatOverrides?: Record<string, string>\n\t\t/** Default values */\n\t\tdefaults?: Partial<T>\n\t\t/** Property name to at-path mapping function */\n\t\ttoAtPath?: (entityPrefix: string, attrName: string) => string\n\t},\n): ISchemaAdapter<T> {\n\tconst shape = zodSchema.shape as Record<string, ZodTypeAny>\n\tconst toAtPath = options?.toAtPath ?? ((prefix, name) => `${prefix}/${name}`)\n\n\tconst attributeDefs: VMAttributeDef[] = Object.entries(shape).map(([name, fieldSchema]: [string, ZodTypeAny]) => {\n\t\tconst isOptional = fieldSchema.isOptional() || fieldSchema.isNullable()\n\t\tconst atPath = options?.atOverrides?.[name] ?? toAtPath(entityPrefix, name)\n\n\t\treturn {\n\t\t\tname,\n\t\t\tatPath,\n\t\t\toptional: isOptional,\n\t\t}\n\t})\n\n\treturn {\n\t\tgetAttributeDefs: () => attributeDefs,\n\t\tgetDefaults: () => (options?.defaults ?? {}) as Partial<T>,\n\t\tgetEntityPrefix: () => entityPrefix,\n\t\tcreateValidator: () => (value: unknown): value is T => zodSchema.safeParse(value).success,\n\t}\n}\n"],"mappings":";AAsBO,SAAS,iBACf,WACA,cACA,SAQoB;AACpB,QAAM,QAAQ,UAAU;AACxB,QAAM,WAAW,SAAS,aAAa,CAAC,QAAQ,SAAS,GAAG,MAAM,IAAI,IAAI;AAE1E,QAAM,gBAAkC,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,WAAW,MAA4B;AAChH,UAAM,aAAa,YAAY,WAAW,KAAK,YAAY,WAAW;AACtE,UAAM,SAAS,SAAS,cAAc,IAAI,KAAK,SAAS,cAAc,IAAI;AAE1E,WAAO;AAAA,MACN;AAAA,MACA;AAAA,MACA,UAAU;AAAA,IACX;AAAA,EACD,CAAC;AAED,SAAO;AAAA,IACN,kBAAkB,MAAM;AAAA,IACxB,aAAa,MAAO,SAAS,YAAY,CAAC;AAAA,IAC1C,iBAAiB,MAAM;AAAA,IACvB,iBAAiB,MAAM,CAAC,UAA+B,UAAU,UAAU,KAAK,EAAE;AAAA,EACnF;AACD;","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -2,23 +2,21 @@ import "./chunk-E46VTKTZ.js";
|
|
|
2
2
|
import "./chunk-7Z5YDQKK.js";
|
|
3
3
|
import {
|
|
4
4
|
fetchSnapshotChainUntil
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-WVW4YXB5.js";
|
|
6
6
|
import {
|
|
7
7
|
agentToShortHash,
|
|
8
8
|
integratePub,
|
|
9
9
|
isShare,
|
|
10
10
|
isSubscription
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-EHO2BFFY.js";
|
|
12
12
|
import {
|
|
13
|
-
includedIn,
|
|
14
|
-
includes,
|
|
15
13
|
liveEntityCollection,
|
|
16
14
|
queryDivergencesByPrev
|
|
17
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-OKXRRWNS.js";
|
|
18
16
|
import {
|
|
19
17
|
updateThreadFromSnapshot,
|
|
20
18
|
withBlockCache
|
|
21
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-VGIACGWX.js";
|
|
22
20
|
import {
|
|
23
21
|
carFromBlob,
|
|
24
22
|
chunkApplogs,
|
|
@@ -35,7 +33,7 @@ import {
|
|
|
35
33
|
prepareSnapshotForPush,
|
|
36
34
|
streamReaderToIterable,
|
|
37
35
|
unchunkApplogsBlock
|
|
38
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-Q4EMPWA3.js";
|
|
39
37
|
import "./chunk-YDAKBU6Q.js";
|
|
40
38
|
import {
|
|
41
39
|
LiveQueryResult,
|
|
@@ -79,7 +77,7 @@ import {
|
|
|
79
77
|
throwOnTimeout,
|
|
80
78
|
withTimeout,
|
|
81
79
|
withoutDeleted
|
|
82
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-2PJFLZRC.js";
|
|
83
81
|
import {
|
|
84
82
|
AppLogNoCidTB,
|
|
85
83
|
AppLogNoCidTBC,
|
|
@@ -88,6 +86,7 @@ import {
|
|
|
88
86
|
CIDTB,
|
|
89
87
|
EntityID,
|
|
90
88
|
EntityID_LENGTH,
|
|
89
|
+
JsonValueTB,
|
|
91
90
|
MULTICODEC_IPNS_KEY,
|
|
92
91
|
MappedThread,
|
|
93
92
|
Nullable,
|
|
@@ -100,6 +99,7 @@ import {
|
|
|
100
99
|
WriteableThread,
|
|
101
100
|
actualize,
|
|
102
101
|
allEntityIDs,
|
|
102
|
+
anyOf,
|
|
103
103
|
applogsByAttrValue,
|
|
104
104
|
applogsByEntity,
|
|
105
105
|
areApplogsEqual,
|
|
@@ -142,6 +142,8 @@ import {
|
|
|
142
142
|
hasPv,
|
|
143
143
|
hasTs,
|
|
144
144
|
holdTillFirstWrite,
|
|
145
|
+
includedIn,
|
|
146
|
+
includes,
|
|
145
147
|
isArrayInitEvent,
|
|
146
148
|
isEncryptedApplog,
|
|
147
149
|
isInitEvent,
|
|
@@ -174,11 +176,13 @@ import {
|
|
|
174
176
|
tryParseCID,
|
|
175
177
|
tsNearlySame,
|
|
176
178
|
uniqueEnFromAppLogs,
|
|
179
|
+
valueEq,
|
|
180
|
+
valueKey,
|
|
177
181
|
variableNameWithoutQuestionmark,
|
|
178
182
|
withAg,
|
|
179
183
|
withPvFrom,
|
|
180
184
|
withTs
|
|
181
|
-
} from "./chunk-
|
|
185
|
+
} from "./chunk-2OXLPZQI.js";
|
|
182
186
|
import {
|
|
183
187
|
BOOL,
|
|
184
188
|
Bool,
|
|
@@ -201,6 +205,7 @@ export {
|
|
|
201
205
|
CIDTB,
|
|
202
206
|
EntityID,
|
|
203
207
|
EntityID_LENGTH,
|
|
208
|
+
JsonValueTB,
|
|
204
209
|
LiveQueryResult,
|
|
205
210
|
MULTICODEC_IPNS_KEY,
|
|
206
211
|
MappedThread,
|
|
@@ -224,6 +229,7 @@ export {
|
|
|
224
229
|
agentToShortHash,
|
|
225
230
|
agentsOfThread,
|
|
226
231
|
allEntityIDs,
|
|
232
|
+
anyOf,
|
|
227
233
|
applogsByAttrValue,
|
|
228
234
|
applogsByEntity,
|
|
229
235
|
areApplogsEqual,
|
|
@@ -359,6 +365,8 @@ export {
|
|
|
359
365
|
unchunkApplogsBlock,
|
|
360
366
|
uniqueEnFromAppLogs,
|
|
361
367
|
updateThreadFromSnapshot,
|
|
368
|
+
valueEq,
|
|
369
|
+
valueKey,
|
|
362
370
|
variableNameWithoutQuestionmark,
|
|
363
371
|
withAg,
|
|
364
372
|
withBlockCache,
|
package/dist/ipfs/car.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"car.d.ts","sourceRoot":"","sources":["../../src/ipfs/car.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAGhD,OAAO,EAAa,GAAG,EAAE,MAAM,cAAc,CAAA;AAE7C,OAAO,EAAU,yBAAyB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAOvF,MAAM,MAAM,SAAS,GAAG,GAAG,CAAA;AAC3B,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAEzD,MAAM,WAAW,aAAa;IAC7B,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,WAAW,CAAC,UAAU,CAAC,CAAA;CACtC;AAED,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,GAAG,CAAA;IAEZ,UAAU,EAAE,aAAa,CAAA;CACzB;AAED,0CAA0C;AAC1C,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,SAAS;;;;;;;;;;;;;;;GAGpD;AAED,wBAAsB,mBAAmB,CACxC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,UAAU,EACnC,eAAe,GAAE,GAAG,EAAO,EAAG,+DAA+D;AAC7F,SAAS,CAAC,EAAE,GAAG;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"car.d.ts","sourceRoot":"","sources":["../../src/ipfs/car.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAGhD,OAAO,EAAa,GAAG,EAAE,MAAM,cAAc,CAAA;AAE7C,OAAO,EAAU,yBAAyB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAOvF,MAAM,MAAM,SAAS,GAAG,GAAG,CAAA;AAC3B,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAEzD,MAAM,WAAW,aAAa;IAC7B,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,WAAW,CAAC,UAAU,CAAC,CAAA;CACtC;AAED,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,GAAG,CAAA;IAEZ,UAAU,EAAE,aAAa,CAAA;CACzB;AAED,0CAA0C;AAC1C,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,SAAS;;;;;;;;;;;;;;;GAGpD;AAED,wBAAsB,mBAAmB,CACxC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,UAAU,EACnC,eAAe,GAAE,GAAG,EAAO,EAAG,+DAA+D;AAC7F,SAAS,CAAC,EAAE,GAAG;;;;;;;;;;;;;;;GAsHf;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,SAAS;;;;;GAmBlD;AACD,wBAAsB,eAAe,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,oBAYxE;AAGD,wBAAsB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,uDASvE,CAAC,iEAAiE;AAWnE,wBAAsB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,iBAQxE;AACD,wBAAsB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAEvE;AAWD,wBAAsB,gBAAgB,CACrC,QAAQ,EAAE,GAAG,EACb,UAAU,EAAE,aAAa,GACvB,OAAO,CAAC,WAAW,EAAE,CAAC,CAiDxB;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,2BAA2B,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,CAWrH"}
|
package/dist/ipfs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
fetchSnapshotChainUntil
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WVW4YXB5.js";
|
|
4
4
|
import {
|
|
5
5
|
carFromBlob,
|
|
6
6
|
collectDagBlocks,
|
|
@@ -11,9 +11,9 @@ import {
|
|
|
11
11
|
makeCarBlob,
|
|
12
12
|
makeCarOut,
|
|
13
13
|
streamReaderToIterable
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-Q4EMPWA3.js";
|
|
15
15
|
import "./chunk-YDAKBU6Q.js";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-2PJFLZRC.js";
|
|
17
17
|
import {
|
|
18
18
|
MULTICODEC_IPNS_KEY,
|
|
19
19
|
areCidsEqual,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
prepareForPub,
|
|
30
30
|
toIpnsString,
|
|
31
31
|
tryParseCID
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-2OXLPZQI.js";
|
|
33
33
|
import "./chunk-ZAADLBSB.js";
|
|
34
34
|
export {
|
|
35
35
|
MULTICODEC_IPNS_KEY,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve an IPNS name to a CID using a public IPFS gateway's HTTP HEAD response.
|
|
4
|
+
*
|
|
5
|
+
* Mechanism: per the IPFS HTTP Gateway spec, `HEAD <gateway>/ipns/<name>/` returns the
|
|
6
|
+
* IPNS-resolved root CID in the `X-Ipfs-Roots` response header (space-separated, ordered
|
|
7
|
+
* from root to leaf). The first entry is the IPNS-resolved CID.
|
|
8
|
+
*
|
|
9
|
+
* This works against any gateway that follows the spec and exposes CORS for HEAD
|
|
10
|
+
* (most public gateways do, e.g. ipfs.zt.ax, ipfs.io, dweb.link).
|
|
11
|
+
*
|
|
12
|
+
* The legacy w3name HTTP endpoint (`GET <base>/name/<ipns>` returning `{value: "/ipfs/<cid>"}`)
|
|
13
|
+
* is also supported here for back-compat with self-hosted w3name-like services — but the
|
|
14
|
+
* X-Ipfs-Roots path is preferred since it's the standardised gateway mechanism.
|
|
15
|
+
*
|
|
16
|
+
* @param ipns - The IPNS name (k51... string)
|
|
17
|
+
* @param gateways - List of gateway base URLs (e.g. `["https://ipfs.zt.ax"]`)
|
|
18
|
+
* @returns The resolved CID, or null if no gateway could resolve the name
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveIPNSViaGateway(ipns: string, gateways: string[]): Promise<CID | null>;
|
|
21
|
+
//# sourceMappingURL=gateway-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway-resolver.d.ts","sourceRoot":"","sources":["../../src/ipns/gateway-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAKtC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAuCjG"}
|
|
@@ -14,21 +14,42 @@ export declare function ipnsNameFromPrivateKey(privKeyBytes: Uint8Array): string
|
|
|
14
14
|
*/
|
|
15
15
|
export declare function createSignedIPNSRecord(privateKey: Uint8Array, cid: CID, sequence: bigint, lifetimeMs?: number): Promise<SignedIPNSRecord>;
|
|
16
16
|
export { unmarshalIPNSRecord };
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* A target that can receive a signed IPNS record, advertise its current
|
|
19
|
+
* sequence, or both.
|
|
20
|
+
*
|
|
21
|
+
* - `publish` is called by `publishIPNSRecord` to actually store the record
|
|
22
|
+
* on the target's backing service. Targets without `publish` are skipped
|
|
23
|
+
* during the fan-out (e.g. a sequence-only source).
|
|
24
|
+
* - `resolveSequence` is consulted by `publishIPNSRecord` to compute the
|
|
25
|
+
* next IPNS sequence. The first target to return a value (including
|
|
26
|
+
* `null` for "never published") wins. Throw to indicate a transient
|
|
27
|
+
* error — the caller will try the next target.
|
|
28
|
+
*
|
|
29
|
+
* Most real targets (e.g. a storage connector) provide both. A simple
|
|
30
|
+
* "track sequence in localStorage" target only needs `resolveSequence`.
|
|
31
|
+
*/
|
|
18
32
|
export interface IPNSPublishTarget {
|
|
19
33
|
name: string;
|
|
20
|
-
publish(ipnsName: string, recordBytes: Uint8Array): Promise<void>;
|
|
34
|
+
publish?(ipnsName: string, recordBytes: Uint8Array): Promise<void>;
|
|
35
|
+
resolveSequence?(ipnsName: string): Promise<bigint | null>;
|
|
21
36
|
}
|
|
22
37
|
/**
|
|
23
|
-
* Resolve current IPNS sequence
|
|
38
|
+
* Resolve the current IPNS sequence from a generic naming service.
|
|
24
39
|
* Returns null if the name was never published (404).
|
|
25
|
-
* Throws on network/server errors.
|
|
40
|
+
* Throws on network/server errors so the caller can try a different target.
|
|
26
41
|
*/
|
|
27
42
|
export declare function resolveIPNSSequence(nameServiceUrl: string, ipnsName: string): Promise<bigint | null>;
|
|
28
43
|
/**
|
|
29
44
|
* Create a signed IPNS record and publish to all configured targets.
|
|
30
|
-
*
|
|
31
|
-
*
|
|
45
|
+
*
|
|
46
|
+
* Sequence resolution: walks `targets` in order asking each one with a
|
|
47
|
+
* `resolveSequence` method. The first target to successfully return a value
|
|
48
|
+
* (including `null` for "never published") determines the next sequence.
|
|
49
|
+
* If every target throws or none supports `resolveSequence`, falls back to 0n.
|
|
50
|
+
*
|
|
51
|
+
* Publish fan-out: only targets with a `publish` method are called.
|
|
52
|
+
* Throws if every publish-capable target fails; partial failures are logged.
|
|
32
53
|
*/
|
|
33
|
-
export declare function publishIPNSRecord(privateKey: Uint8Array, cid: CID, targets: IPNSPublishTarget[]
|
|
54
|
+
export declare function publishIPNSRecord(privateKey: Uint8Array, cid: CID, targets: IPNSPublishTarget[]): Promise<SignedIPNSRecord>;
|
|
34
55
|
//# sourceMappingURL=ipns-record.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipns-record.d.ts","sourceRoot":"","sources":["../../src/ipns/ipns-record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,mBAAmB,EAAE,MAAM,MAAM,CAAA;AAI/E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C,MAAM,WAAW,gBAAgB;IAChC,WAAW,EAAE,UAAU,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,UAAU,GAAG,MAAM,CAGvE;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC3C,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,UAAU,SAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC,CAO3B;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAA;AAE9B
|
|
1
|
+
{"version":3,"file":"ipns-record.d.ts","sourceRoot":"","sources":["../../src/ipns/ipns-record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,mBAAmB,EAAE,MAAM,MAAM,CAAA;AAI/E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C,MAAM,WAAW,gBAAgB;IAChC,WAAW,EAAE,UAAU,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,UAAU,GAAG,MAAM,CAGvE;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC3C,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,UAAU,SAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC,CAO3B;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAA;AAE9B;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClE,eAAe,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;CAC1D;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACxC,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2BxB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACtC,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,iBAAiB,EAAE,GAC1B,OAAO,CAAC,gBAAgB,CAAC,CA2B3B"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { IPNSPublishTarget } from '@wovin/core/ipns';
|
|
2
|
+
import { CID } from 'multiformats/cid';
|
|
3
|
+
import * as W3Name from 'w3name';
|
|
4
|
+
/**
|
|
5
|
+
* Publish CID to IPNS, automatically handling increment vs v0.
|
|
6
|
+
* Returns the revision for further processing (e.g., Kubo integration).
|
|
7
|
+
*/
|
|
8
|
+
export declare function publishIPNS(ipnsPrivateKey: Uint8Array, cid: CID): Promise<W3Name.Revision>;
|
|
9
|
+
/**
|
|
10
|
+
* Create an IPNSPublishTarget that publishes to W3Name service via HTTP POST.
|
|
11
|
+
*/
|
|
12
|
+
export declare function w3nameTarget(serviceUrl?: string): IPNSPublishTarget;
|
|
13
|
+
export declare function generateIpnsKey(): Promise<W3Name.WritableName>;
|
|
14
|
+
export declare function getW3NamePublic(pk: Uint8Array): Promise<string>;
|
|
15
|
+
//# sourceMappingURL=ipns-w3name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipns-w3name.d.ts","sourceRoot":"","sources":["../../src/ipns/ipns-w3name.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAGzD,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAwChC;;;GAGG;AACH,wBAAsB,WAAW,CAAC,cAAc,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAMhG;AAyBD;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,SAA8B,GAAG,iBAAiB,CAWxF;AAED,wBAAsB,eAAe,iCAEpC;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,UAAU,mBAGnD"}
|