@wovin/core 0.2.2 → 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/datom-types.d.ts.map +1 -1
- package/dist/applog.js +1 -1
- package/dist/blockstore.js +2 -0
- package/dist/blockstore.js.map +1 -1
- package/dist/{chunk-SHUHRHOT.js → chunk-2OXLPZQI.js} +10 -3
- package/dist/chunk-2OXLPZQI.js.map +1 -0
- package/dist/{chunk-3SUFNJEZ.js → chunk-2PJFLZRC.js} +7 -2
- package/dist/{chunk-3SUFNJEZ.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-OC6Z6CQW.js → chunk-EHO2BFFY.js} +2 -2
- package/dist/chunk-ICBK7NC4.js +27 -0
- package/dist/chunk-ICBK7NC4.js.map +1 -0
- package/dist/{chunk-22WDFLXO.js → chunk-OKXRRWNS.js} +3 -3
- package/dist/{chunk-6ALNRM3J.js → chunk-Q4EMPWA3.js} +15 -8
- package/dist/chunk-Q4EMPWA3.js.map +1 -0
- package/dist/{chunk-HUIQ54TT.js → chunk-VGIACGWX.js} +3 -3
- package/dist/{chunk-BLF5MAWU.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 +7 -7
- 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.js +3 -3
- package/dist/retrieve.js +4 -4
- 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/datom-types.ts +2 -2
- 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 +6 -5
- 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-6ALNRM3J.js.map +0 -1
- package/dist/chunk-SHUHRHOT.js.map +0 -1
- /package/dist/{chunk-OC6Z6CQW.js.map → chunk-EHO2BFFY.js.map} +0 -0
- /package/dist/{chunk-22WDFLXO.js.map → chunk-OKXRRWNS.js.map} +0 -0
- /package/dist/{chunk-HUIQ54TT.js.map → chunk-VGIACGWX.js.map} +0 -0
- /package/dist/{chunk-BLF5MAWU.js.map → chunk-WVW4YXB5.js.map} +0 -0
|
@@ -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,21 +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
13
|
liveEntityCollection,
|
|
14
14
|
queryDivergencesByPrev
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-OKXRRWNS.js";
|
|
16
16
|
import {
|
|
17
17
|
updateThreadFromSnapshot,
|
|
18
18
|
withBlockCache
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-VGIACGWX.js";
|
|
20
20
|
import {
|
|
21
21
|
carFromBlob,
|
|
22
22
|
chunkApplogs,
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
prepareSnapshotForPush,
|
|
34
34
|
streamReaderToIterable,
|
|
35
35
|
unchunkApplogsBlock
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-Q4EMPWA3.js";
|
|
37
37
|
import "./chunk-YDAKBU6Q.js";
|
|
38
38
|
import {
|
|
39
39
|
LiveQueryResult,
|
|
@@ -77,7 +77,7 @@ import {
|
|
|
77
77
|
throwOnTimeout,
|
|
78
78
|
withTimeout,
|
|
79
79
|
withoutDeleted
|
|
80
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-2PJFLZRC.js";
|
|
81
81
|
import {
|
|
82
82
|
AppLogNoCidTB,
|
|
83
83
|
AppLogNoCidTBC,
|
|
@@ -182,7 +182,7 @@ import {
|
|
|
182
182
|
withAg,
|
|
183
183
|
withPvFrom,
|
|
184
184
|
withTs
|
|
185
|
-
} from "./chunk-
|
|
185
|
+
} from "./chunk-2OXLPZQI.js";
|
|
186
186
|
import {
|
|
187
187
|
BOOL,
|
|
188
188
|
Bool,
|
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"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid';
|
|
2
|
+
import { type Options as PartysocketOptions } from 'partysocket/ws';
|
|
3
|
+
export type { PartysocketOptions };
|
|
4
|
+
export interface W3NameRecord {
|
|
5
|
+
value: string;
|
|
6
|
+
seq?: number;
|
|
7
|
+
validity?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Debug info provided when a stale WebSocket connection is detected.
|
|
11
|
+
*/
|
|
12
|
+
export interface StaleConnectionInfo {
|
|
13
|
+
/** When the WebSocket connection was established */
|
|
14
|
+
connectedAt: Date;
|
|
15
|
+
/** When we last received a WebSocket message */
|
|
16
|
+
lastMessageAt: Date | null;
|
|
17
|
+
/** How long since last message (ms) */
|
|
18
|
+
silenceDuration: number;
|
|
19
|
+
/** The stale value from WebSocket */
|
|
20
|
+
staleValue: string | null;
|
|
21
|
+
/** The current value from HTTP */
|
|
22
|
+
currentValue: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Enriched IPNS update with parsed CID and change detection.
|
|
26
|
+
* Backwards compatible - `.value` still works as before.
|
|
27
|
+
*/
|
|
28
|
+
export interface IpnsUpdate {
|
|
29
|
+
/** Raw IPNS value string (e.g. '/ipfs/bafy...') — same as W3NameRecord.value */
|
|
30
|
+
value: string;
|
|
31
|
+
/** Parsed CID if value is valid IPFS path, null otherwise */
|
|
32
|
+
cid: CID | null;
|
|
33
|
+
/** Previous value (null on first update) */
|
|
34
|
+
lastValue: string | null;
|
|
35
|
+
/** Whether this is a change from lastValue */
|
|
36
|
+
isNew: boolean;
|
|
37
|
+
/** Original W3NameRecord for access to seq/validity */
|
|
38
|
+
record: W3NameRecord;
|
|
39
|
+
}
|
|
40
|
+
export interface WatchRawOptions {
|
|
41
|
+
/** Called when the IPNS record is updated */
|
|
42
|
+
onUpdate: (record: W3NameRecord) => void;
|
|
43
|
+
/** Called when an error occurs */
|
|
44
|
+
onError?: (error: Event | Error) => void;
|
|
45
|
+
/** Called when the connection is opened */
|
|
46
|
+
onOpen?: () => void;
|
|
47
|
+
/** Called when the connection is closed */
|
|
48
|
+
onClose?: (event: CloseEvent) => void;
|
|
49
|
+
}
|
|
50
|
+
export interface WatchRawSubscription {
|
|
51
|
+
/** Close the WebSocket connection */
|
|
52
|
+
close: () => void;
|
|
53
|
+
/** The underlying WebSocket instance */
|
|
54
|
+
ws: WebSocket;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Low-level WebSocket watcher for IPNS (no reconnect logic).
|
|
58
|
+
* Use this when you want full control over connection lifecycle.
|
|
59
|
+
* For most cases, prefer `watchName` or `IpnsWatcher` which handle reconnection.
|
|
60
|
+
*
|
|
61
|
+
* @param nameBaseUrl - Base URL of a naming service that supports `/name/<ipns>/watch` (WebSocket) and `/name/<ipns>` (HTTP)
|
|
62
|
+
* @param name - The IPNS name/key to watch
|
|
63
|
+
* @param options - Callback options
|
|
64
|
+
* @returns Subscription with close() and ws
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* const sub = watchNameRaw('https://name.example.com', 'k51qzi5u...', {
|
|
69
|
+
* onUpdate: (record) => console.log('Update:', record.value),
|
|
70
|
+
* onClose: () => console.log('Disconnected - handle reconnect yourself'),
|
|
71
|
+
* })
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function watchNameRaw(nameBaseUrl: string, name: string, options: WatchRawOptions): WatchRawSubscription;
|
|
75
|
+
export interface IpnsWatcherOptions {
|
|
76
|
+
/** Called when the IPNS record is updated (enriched payload with CID and change detection) */
|
|
77
|
+
onUpdate: (update: IpnsUpdate) => void | Promise<void>;
|
|
78
|
+
/** Called when an error occurs */
|
|
79
|
+
onError?: (error: Error | Event) => void;
|
|
80
|
+
/** Called when the connection is opened/reconnected */
|
|
81
|
+
onConnected?: () => void;
|
|
82
|
+
/** Called when the connection is closed */
|
|
83
|
+
onDisconnected?: () => void;
|
|
84
|
+
/** Fetch current IPNS state on first connect (default: false) */
|
|
85
|
+
fetchInitialState?: boolean;
|
|
86
|
+
/** Fetch current IPNS state on reconnect to catch missed updates (default: true) */
|
|
87
|
+
catchUpOnReconnect?: boolean;
|
|
88
|
+
/** If true, call onUpdate even when value hasn't changed (default: false) */
|
|
89
|
+
includeUnchanged?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Enable periodic liveness checks via HTTP to detect zombie connections (default: true).
|
|
92
|
+
* When enabled, periodically fetches current IPNS value and forces reconnect if it
|
|
93
|
+
* differs from the last WebSocket update.
|
|
94
|
+
*/
|
|
95
|
+
livenessCheck?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Liveness check interval in milliseconds (default: 3600000 = 1 hour).
|
|
98
|
+
* Only used when livenessCheck is enabled.
|
|
99
|
+
*/
|
|
100
|
+
livenessCheckInterval?: number;
|
|
101
|
+
/**
|
|
102
|
+
* Called when a stale connection is detected (WebSocket missed updates).
|
|
103
|
+
* Provides debug info about the connection state.
|
|
104
|
+
*/
|
|
105
|
+
onStaleConnection?: (info: StaleConnectionInfo) => void;
|
|
106
|
+
/**
|
|
107
|
+
* Partysocket options (passed through to ReconnectingWebSocket).
|
|
108
|
+
* Useful options: startClosed, maxReconnectionDelay, minReconnectionDelay, etc.
|
|
109
|
+
* @see https://github.com/partykit/partykit/tree/main/packages/partysocket
|
|
110
|
+
*/
|
|
111
|
+
wsOptions?: PartysocketOptions;
|
|
112
|
+
}
|
|
113
|
+
export declare class IpnsWatcher {
|
|
114
|
+
private name;
|
|
115
|
+
private nameBaseUrl;
|
|
116
|
+
private ws;
|
|
117
|
+
private lastKnownValue;
|
|
118
|
+
private options;
|
|
119
|
+
private isFirstConnect;
|
|
120
|
+
private livenessTimer;
|
|
121
|
+
private connectedAt;
|
|
122
|
+
private lastMessageAt;
|
|
123
|
+
constructor(nameBaseUrl: string, name: string, options: IpnsWatcherOptions);
|
|
124
|
+
/**
|
|
125
|
+
* Resolve current IPNS value via HTTP API to catch missed updates
|
|
126
|
+
*/
|
|
127
|
+
private checkForMissedUpdates;
|
|
128
|
+
/**
|
|
129
|
+
* Start periodic liveness checks to detect zombie connections.
|
|
130
|
+
*/
|
|
131
|
+
private startLivenessCheck;
|
|
132
|
+
/**
|
|
133
|
+
* Stop periodic liveness checks.
|
|
134
|
+
*/
|
|
135
|
+
private stopLivenessCheck;
|
|
136
|
+
/**
|
|
137
|
+
* Perform a single liveness check via HTTP.
|
|
138
|
+
* If the HTTP value differs from lastKnownValue, the connection is stale.
|
|
139
|
+
*/
|
|
140
|
+
private performLivenessCheck;
|
|
141
|
+
/**
|
|
142
|
+
* Manually start/reconnect the WebSocket.
|
|
143
|
+
* Only needed if you used `wsOptions: { startClosed: true }`.
|
|
144
|
+
*/
|
|
145
|
+
start(): void;
|
|
146
|
+
/**
|
|
147
|
+
* Alias for close() - for backward compatibility
|
|
148
|
+
*/
|
|
149
|
+
stop(): void;
|
|
150
|
+
/**
|
|
151
|
+
* Close the WebSocket connection and stop watching
|
|
152
|
+
*/
|
|
153
|
+
close(): void;
|
|
154
|
+
/**
|
|
155
|
+
* Get the last known IPNS value
|
|
156
|
+
*/
|
|
157
|
+
get lastValue(): string | null;
|
|
158
|
+
/**
|
|
159
|
+
* Get the WebSocket ready state
|
|
160
|
+
*/
|
|
161
|
+
get readyState(): number;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Create an IPNS watcher with auto-reconnect and catch-up logic.
|
|
165
|
+
* Convenience function that creates and returns an IpnsWatcher instance.
|
|
166
|
+
*
|
|
167
|
+
* @param nameBaseUrl - Base URL of a naming service that supports `/name/<ipns>/watch` (WebSocket) and `/name/<ipns>` (HTTP)
|
|
168
|
+
* @param name - The IPNS name/key to watch (e.g. "k51qzi5u...")
|
|
169
|
+
* @param options - Callback options for handling events
|
|
170
|
+
* @returns An IpnsWatcher instance with close() method
|
|
171
|
+
*/
|
|
172
|
+
export declare function watchName(nameBaseUrl: string, name: string, options: IpnsWatcherOptions): IpnsWatcher;
|
|
173
|
+
/**
|
|
174
|
+
* Watch an IPNS name and return updates as an async iterator.
|
|
175
|
+
* Includes auto-reconnect - iterator continues through disconnections.
|
|
176
|
+
*
|
|
177
|
+
* @param nameBaseUrl - Base URL of a naming service that supports `/name/<ipns>/watch` (WebSocket) and `/name/<ipns>` (HTTP)
|
|
178
|
+
* @param name - The IPNS name/key to watch
|
|
179
|
+
* @param signal - Optional AbortSignal to stop the watch
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* const controller = new AbortController()
|
|
184
|
+
* for await (const update of watchNameIterator('https://name.example.com', 'k51qzi5u...', controller.signal)) {
|
|
185
|
+
* console.log('Update:', update.cid?.toString())
|
|
186
|
+
* }
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
export declare function watchNameIterator(nameBaseUrl: string, name: string, signal?: AbortSignal): AsyncGenerator<IpnsUpdate, void, unknown>;
|
|
190
|
+
//# sourceMappingURL=ipns-watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipns-watcher.d.ts","sourceRoot":"","sources":["../../src/ipns/ipns-watcher.ts"],"names":[],"mappings":"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"}
|
package/dist/ipns.d.ts
CHANGED
package/dist/ipns.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipns.d.ts","sourceRoot":"","sources":["../src/ipns.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAA"}
|
|
1
|
+
{"version":3,"file":"ipns.d.ts","sourceRoot":"","sources":["../src/ipns.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA"}
|