@weaveprotocol/core 0.1.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.
Files changed (430) hide show
  1. package/README.md +1106 -0
  2. package/dist/elements/auth-styles.d.ts +18 -0
  3. package/dist/elements/auth-styles.d.ts.map +1 -0
  4. package/dist/elements/auth-styles.js +150 -0
  5. package/dist/elements/auth-styles.js.map +1 -0
  6. package/dist/elements/dom.d.ts +28 -0
  7. package/dist/elements/dom.d.ts.map +1 -0
  8. package/dist/elements/dom.js +74 -0
  9. package/dist/elements/dom.js.map +1 -0
  10. package/dist/elements/index.d.ts +13 -0
  11. package/dist/elements/index.d.ts.map +1 -0
  12. package/dist/elements/index.js +11 -0
  13. package/dist/elements/index.js.map +1 -0
  14. package/dist/elements/weave-auth.d.ts +52 -0
  15. package/dist/elements/weave-auth.d.ts.map +1 -0
  16. package/dist/elements/weave-auth.js +427 -0
  17. package/dist/elements/weave-auth.js.map +1 -0
  18. package/dist/identity/account-store.d.ts +113 -0
  19. package/dist/identity/account-store.d.ts.map +1 -0
  20. package/dist/identity/account-store.js +305 -0
  21. package/dist/identity/account-store.js.map +1 -0
  22. package/dist/identity/account-vault.d.ts +199 -0
  23. package/dist/identity/account-vault.d.ts.map +1 -0
  24. package/dist/identity/account-vault.js +251 -0
  25. package/dist/identity/account-vault.js.map +1 -0
  26. package/dist/identity/agent-note.d.ts +19 -0
  27. package/dist/identity/agent-note.d.ts.map +1 -0
  28. package/dist/identity/agent-note.js +29 -0
  29. package/dist/identity/agent-note.js.map +1 -0
  30. package/dist/identity/crypto-p256.d.ts +7 -0
  31. package/dist/identity/crypto-p256.d.ts.map +1 -0
  32. package/dist/identity/crypto-p256.js +84 -0
  33. package/dist/identity/crypto-p256.js.map +1 -0
  34. package/dist/identity/device-key.d.ts +60 -0
  35. package/dist/identity/device-key.d.ts.map +1 -0
  36. package/dist/identity/device-key.js +103 -0
  37. package/dist/identity/device-key.js.map +1 -0
  38. package/dist/identity/did.d.ts +22 -0
  39. package/dist/identity/did.d.ts.map +1 -0
  40. package/dist/identity/did.js +37 -0
  41. package/dist/identity/did.js.map +1 -0
  42. package/dist/identity/folder-account.d.ts +65 -0
  43. package/dist/identity/folder-account.d.ts.map +1 -0
  44. package/dist/identity/folder-account.js +115 -0
  45. package/dist/identity/folder-account.js.map +1 -0
  46. package/dist/identity/identity-manager.d.ts +36 -0
  47. package/dist/identity/identity-manager.d.ts.map +1 -0
  48. package/dist/identity/identity-manager.js +115 -0
  49. package/dist/identity/identity-manager.js.map +1 -0
  50. package/dist/identity/index.d.ts +10 -0
  51. package/dist/identity/index.d.ts.map +1 -0
  52. package/dist/identity/index.js +10 -0
  53. package/dist/identity/index.js.map +1 -0
  54. package/dist/identity/keys.d.ts +24 -0
  55. package/dist/identity/keys.d.ts.map +1 -0
  56. package/dist/identity/keys.js +38 -0
  57. package/dist/identity/keys.js.map +1 -0
  58. package/dist/identity/pairing.d.ts +83 -0
  59. package/dist/identity/pairing.d.ts.map +1 -0
  60. package/dist/identity/pairing.js +120 -0
  61. package/dist/identity/pairing.js.map +1 -0
  62. package/dist/identity/passkey-diagnostics.d.ts +54 -0
  63. package/dist/identity/passkey-diagnostics.d.ts.map +1 -0
  64. package/dist/identity/passkey-diagnostics.js +178 -0
  65. package/dist/identity/passkey-diagnostics.js.map +1 -0
  66. package/dist/identity/recovery-code.d.ts +50 -0
  67. package/dist/identity/recovery-code.d.ts.map +1 -0
  68. package/dist/identity/recovery-code.js +116 -0
  69. package/dist/identity/recovery-code.js.map +1 -0
  70. package/dist/identity/root-signer.d.ts +59 -0
  71. package/dist/identity/root-signer.d.ts.map +1 -0
  72. package/dist/identity/root-signer.js +44 -0
  73. package/dist/identity/root-signer.js.map +1 -0
  74. package/dist/identity/ucan.d.ts +164 -0
  75. package/dist/identity/ucan.d.ts.map +1 -0
  76. package/dist/identity/ucan.js +273 -0
  77. package/dist/identity/ucan.js.map +1 -0
  78. package/dist/identity/webauthn.d.ts +87 -0
  79. package/dist/identity/webauthn.d.ts.map +1 -0
  80. package/dist/identity/webauthn.js +155 -0
  81. package/dist/identity/webauthn.js.map +1 -0
  82. package/dist/index.d.ts +116 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +85 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/network/index.d.ts +17 -0
  87. package/dist/network/index.d.ts.map +1 -0
  88. package/dist/network/index.js +10 -0
  89. package/dist/network/index.js.map +1 -0
  90. package/dist/network/introductions.d.ts +85 -0
  91. package/dist/network/introductions.d.ts.map +1 -0
  92. package/dist/network/introductions.js +94 -0
  93. package/dist/network/introductions.js.map +1 -0
  94. package/dist/network/local-transport.d.ts +22 -0
  95. package/dist/network/local-transport.d.ts.map +1 -0
  96. package/dist/network/local-transport.js +55 -0
  97. package/dist/network/local-transport.js.map +1 -0
  98. package/dist/network/mesh.d.ts +31 -0
  99. package/dist/network/mesh.d.ts.map +1 -0
  100. package/dist/network/mesh.js +332 -0
  101. package/dist/network/mesh.js.map +1 -0
  102. package/dist/network/multi-signaling.d.ts +29 -0
  103. package/dist/network/multi-signaling.d.ts.map +1 -0
  104. package/dist/network/multi-signaling.js +125 -0
  105. package/dist/network/multi-signaling.js.map +1 -0
  106. package/dist/network/network-manager.d.ts +37 -0
  107. package/dist/network/network-manager.d.ts.map +1 -0
  108. package/dist/network/network-manager.js +64 -0
  109. package/dist/network/network-manager.js.map +1 -0
  110. package/dist/network/peer-auth.d.ts +98 -0
  111. package/dist/network/peer-auth.d.ts.map +1 -0
  112. package/dist/network/peer-auth.js +86 -0
  113. package/dist/network/peer-auth.js.map +1 -0
  114. package/dist/network/rtc-transport.d.ts +18 -0
  115. package/dist/network/rtc-transport.d.ts.map +1 -0
  116. package/dist/network/rtc-transport.js +149 -0
  117. package/dist/network/rtc-transport.js.map +1 -0
  118. package/dist/network/signaling.d.ts +40 -0
  119. package/dist/network/signaling.d.ts.map +1 -0
  120. package/dist/network/signaling.js +124 -0
  121. package/dist/network/signaling.js.map +1 -0
  122. package/dist/network/transport.d.ts +50 -0
  123. package/dist/network/transport.d.ts.map +1 -0
  124. package/dist/network/transport.js +13 -0
  125. package/dist/network/transport.js.map +1 -0
  126. package/dist/network/ws-transport.d.ts +42 -0
  127. package/dist/network/ws-transport.d.ts.map +1 -0
  128. package/dist/network/ws-transport.js +194 -0
  129. package/dist/network/ws-transport.js.map +1 -0
  130. package/dist/node/actions.d.ts +62 -0
  131. package/dist/node/actions.d.ts.map +1 -0
  132. package/dist/node/actions.js +500 -0
  133. package/dist/node/actions.js.map +1 -0
  134. package/dist/node/carrier.d.ts +85 -0
  135. package/dist/node/carrier.d.ts.map +1 -0
  136. package/dist/node/carrier.js +192 -0
  137. package/dist/node/carrier.js.map +1 -0
  138. package/dist/node/copy.d.ts +38 -0
  139. package/dist/node/copy.d.ts.map +1 -0
  140. package/dist/node/copy.js +53 -0
  141. package/dist/node/copy.js.map +1 -0
  142. package/dist/node/index.d.ts +16 -0
  143. package/dist/node/index.d.ts.map +1 -0
  144. package/dist/node/index.js +11 -0
  145. package/dist/node/index.js.map +1 -0
  146. package/dist/node/node.d.ts +12 -0
  147. package/dist/node/node.d.ts.map +1 -0
  148. package/dist/node/node.js +872 -0
  149. package/dist/node/node.js.map +1 -0
  150. package/dist/node/space-runtime.d.ts +144 -0
  151. package/dist/node/space-runtime.d.ts.map +1 -0
  152. package/dist/node/space-runtime.js +1221 -0
  153. package/dist/node/space-runtime.js.map +1 -0
  154. package/dist/node/stores.d.ts +45 -0
  155. package/dist/node/stores.d.ts.map +1 -0
  156. package/dist/node/stores.js +31 -0
  157. package/dist/node/stores.js.map +1 -0
  158. package/dist/node/types.d.ts +508 -0
  159. package/dist/node/types.d.ts.map +1 -0
  160. package/dist/node/types.js +2 -0
  161. package/dist/node/types.js.map +1 -0
  162. package/dist/privacy/index.d.ts +4 -0
  163. package/dist/privacy/index.d.ts.map +1 -0
  164. package/dist/privacy/index.js +4 -0
  165. package/dist/privacy/index.js.map +1 -0
  166. package/dist/privacy/key-distribution.d.ts +42 -0
  167. package/dist/privacy/key-distribution.d.ts.map +1 -0
  168. package/dist/privacy/key-distribution.js +50 -0
  169. package/dist/privacy/key-distribution.js.map +1 -0
  170. package/dist/privacy/privacy-guard.d.ts +24 -0
  171. package/dist/privacy/privacy-guard.d.ts.map +1 -0
  172. package/dist/privacy/privacy-guard.js +87 -0
  173. package/dist/privacy/privacy-guard.js.map +1 -0
  174. package/dist/privacy/space-encryption.d.ts +48 -0
  175. package/dist/privacy/space-encryption.d.ts.map +1 -0
  176. package/dist/privacy/space-encryption.js +61 -0
  177. package/dist/privacy/space-encryption.js.map +1 -0
  178. package/dist/query/engine.d.ts +27 -0
  179. package/dist/query/engine.d.ts.map +1 -0
  180. package/dist/query/engine.js +84 -0
  181. package/dist/query/engine.js.map +1 -0
  182. package/dist/query/filter.d.ts +15 -0
  183. package/dist/query/filter.d.ts.map +1 -0
  184. package/dist/query/filter.js +207 -0
  185. package/dist/query/filter.js.map +1 -0
  186. package/dist/query/types.d.ts +144 -0
  187. package/dist/query/types.d.ts.map +1 -0
  188. package/dist/query/types.js +22 -0
  189. package/dist/query/types.js.map +1 -0
  190. package/dist/react/context.d.ts +81 -0
  191. package/dist/react/context.d.ts.map +1 -0
  192. package/dist/react/context.js +95 -0
  193. package/dist/react/context.js.map +1 -0
  194. package/dist/react/index.d.ts +40 -0
  195. package/dist/react/index.d.ts.map +1 -0
  196. package/dist/react/index.js +36 -0
  197. package/dist/react/index.js.map +1 -0
  198. package/dist/react/use-live.d.ts +16 -0
  199. package/dist/react/use-live.d.ts.map +1 -0
  200. package/dist/react/use-live.js +55 -0
  201. package/dist/react/use-live.js.map +1 -0
  202. package/dist/react/use-query.d.ts +17 -0
  203. package/dist/react/use-query.d.ts.map +1 -0
  204. package/dist/react/use-query.js +23 -0
  205. package/dist/react/use-query.js.map +1 -0
  206. package/dist/react/use-space.d.ts +29 -0
  207. package/dist/react/use-space.d.ts.map +1 -0
  208. package/dist/react/use-space.js +48 -0
  209. package/dist/react/use-space.js.map +1 -0
  210. package/dist/react/use-spaces.d.ts +19 -0
  211. package/dist/react/use-spaces.d.ts.map +1 -0
  212. package/dist/react/use-spaces.js +55 -0
  213. package/dist/react/use-spaces.js.map +1 -0
  214. package/dist/react/use-weave-auth.d.ts +10 -0
  215. package/dist/react/use-weave-auth.d.ts.map +1 -0
  216. package/dist/react/use-weave-auth.js +15 -0
  217. package/dist/react/use-weave-auth.js.map +1 -0
  218. package/dist/react/weave-auth.d.ts +17 -0
  219. package/dist/react/weave-auth.d.ts.map +1 -0
  220. package/dist/react/weave-auth.js +38 -0
  221. package/dist/react/weave-auth.js.map +1 -0
  222. package/dist/records/describe.d.ts +38 -0
  223. package/dist/records/describe.d.ts.map +1 -0
  224. package/dist/records/describe.js +101 -0
  225. package/dist/records/describe.js.map +1 -0
  226. package/dist/records/links.d.ts +14 -0
  227. package/dist/records/links.d.ts.map +1 -0
  228. package/dist/records/links.js +25 -0
  229. package/dist/records/links.js.map +1 -0
  230. package/dist/records/rules.d.ts +59 -0
  231. package/dist/records/rules.d.ts.map +1 -0
  232. package/dist/records/rules.js +118 -0
  233. package/dist/records/rules.js.map +1 -0
  234. package/dist/records/version.d.ts +54 -0
  235. package/dist/records/version.d.ts.map +1 -0
  236. package/dist/records/version.js +70 -0
  237. package/dist/records/version.js.map +1 -0
  238. package/dist/schema/collection-def.d.ts +96 -0
  239. package/dist/schema/collection-def.d.ts.map +1 -0
  240. package/dist/schema/collection-def.js +272 -0
  241. package/dist/schema/collection-def.js.map +1 -0
  242. package/dist/schema/expression.d.ts +69 -0
  243. package/dist/schema/expression.d.ts.map +1 -0
  244. package/dist/schema/expression.js +92 -0
  245. package/dist/schema/expression.js.map +1 -0
  246. package/dist/schema/index.d.ts +4 -0
  247. package/dist/schema/index.d.ts.map +1 -0
  248. package/dist/schema/index.js +4 -0
  249. package/dist/schema/index.js.map +1 -0
  250. package/dist/schema/schema-engine.d.ts +42 -0
  251. package/dist/schema/schema-engine.d.ts.map +1 -0
  252. package/dist/schema/schema-engine.js +36 -0
  253. package/dist/schema/schema-engine.js.map +1 -0
  254. package/dist/schema/signer.d.ts +27 -0
  255. package/dist/schema/signer.d.ts.map +1 -0
  256. package/dist/schema/signer.js +36 -0
  257. package/dist/schema/signer.js.map +1 -0
  258. package/dist/schemas/apps.d.ts +88 -0
  259. package/dist/schemas/apps.d.ts.map +1 -0
  260. package/dist/schemas/apps.js +168 -0
  261. package/dist/schemas/apps.js.map +1 -0
  262. package/dist/schemas/index.d.ts +410 -0
  263. package/dist/schemas/index.d.ts.map +1 -0
  264. package/dist/schemas/index.js +208 -0
  265. package/dist/schemas/index.js.map +1 -0
  266. package/dist/schemas/screens.d.ts +67 -0
  267. package/dist/schemas/screens.d.ts.map +1 -0
  268. package/dist/schemas/screens.js +242 -0
  269. package/dist/schemas/screens.js.map +1 -0
  270. package/dist/session/agent-link.d.ts +79 -0
  271. package/dist/session/agent-link.d.ts.map +1 -0
  272. package/dist/session/agent-link.js +251 -0
  273. package/dist/session/agent-link.js.map +1 -0
  274. package/dist/session/auth.d.ts +233 -0
  275. package/dist/session/auth.d.ts.map +1 -0
  276. package/dist/session/auth.js +783 -0
  277. package/dist/session/auth.js.map +1 -0
  278. package/dist/session/connect.d.ts +211 -0
  279. package/dist/session/connect.d.ts.map +1 -0
  280. package/dist/session/connect.js +355 -0
  281. package/dist/session/connect.js.map +1 -0
  282. package/dist/session/connection.d.ts +70 -0
  283. package/dist/session/connection.d.ts.map +1 -0
  284. package/dist/session/connection.js +120 -0
  285. package/dist/session/connection.js.map +1 -0
  286. package/dist/session/credentials.d.ts +44 -0
  287. package/dist/session/credentials.d.ts.map +1 -0
  288. package/dist/session/credentials.js +60 -0
  289. package/dist/session/credentials.js.map +1 -0
  290. package/dist/session/index.d.ts +25 -0
  291. package/dist/session/index.d.ts.map +1 -0
  292. package/dist/session/index.js +18 -0
  293. package/dist/session/index.js.map +1 -0
  294. package/dist/session/pairing.d.ts +59 -0
  295. package/dist/session/pairing.d.ts.map +1 -0
  296. package/dist/session/pairing.js +144 -0
  297. package/dist/session/pairing.js.map +1 -0
  298. package/dist/session/places.d.ts +62 -0
  299. package/dist/session/places.d.ts.map +1 -0
  300. package/dist/session/places.js +101 -0
  301. package/dist/session/places.js.map +1 -0
  302. package/dist/session/stay-signed-in.d.ts +37 -0
  303. package/dist/session/stay-signed-in.d.ts.map +1 -0
  304. package/dist/session/stay-signed-in.js +124 -0
  305. package/dist/session/stay-signed-in.js.map +1 -0
  306. package/dist/space/account-registry.d.ts +64 -0
  307. package/dist/space/account-registry.d.ts.map +1 -0
  308. package/dist/space/account-registry.js +66 -0
  309. package/dist/space/account-registry.js.map +1 -0
  310. package/dist/space/index.d.ts +3 -0
  311. package/dist/space/index.d.ts.map +1 -0
  312. package/dist/space/index.js +3 -0
  313. package/dist/space/index.js.map +1 -0
  314. package/dist/space/pass.d.ts +63 -0
  315. package/dist/space/pass.d.ts.map +1 -0
  316. package/dist/space/pass.js +54 -0
  317. package/dist/space/pass.js.map +1 -0
  318. package/dist/space/presets.d.ts +31 -0
  319. package/dist/space/presets.d.ts.map +1 -0
  320. package/dist/space/presets.js +24 -0
  321. package/dist/space/presets.js.map +1 -0
  322. package/dist/space/roles.d.ts +186 -0
  323. package/dist/space/roles.d.ts.map +1 -0
  324. package/dist/space/roles.js +500 -0
  325. package/dist/space/roles.js.map +1 -0
  326. package/dist/space/space-access.d.ts +80 -0
  327. package/dist/space/space-access.d.ts.map +1 -0
  328. package/dist/space/space-access.js +135 -0
  329. package/dist/space/space-access.js.map +1 -0
  330. package/dist/space/space-manager.d.ts +87 -0
  331. package/dist/space/space-manager.d.ts.map +1 -0
  332. package/dist/space/space-manager.js +187 -0
  333. package/dist/space/space-manager.js.map +1 -0
  334. package/dist/storage/directory-access.d.ts +78 -0
  335. package/dist/storage/directory-access.d.ts.map +1 -0
  336. package/dist/storage/directory-access.js +164 -0
  337. package/dist/storage/directory-access.js.map +1 -0
  338. package/dist/storage/encrypted-adapter.d.ts +49 -0
  339. package/dist/storage/encrypted-adapter.d.ts.map +1 -0
  340. package/dist/storage/encrypted-adapter.js +106 -0
  341. package/dist/storage/encrypted-adapter.js.map +1 -0
  342. package/dist/storage/folder-adapter.d.ts +105 -0
  343. package/dist/storage/folder-adapter.d.ts.map +1 -0
  344. package/dist/storage/folder-adapter.js +280 -0
  345. package/dist/storage/folder-adapter.js.map +1 -0
  346. package/dist/storage/folder-reconcile.d.ts +53 -0
  347. package/dist/storage/folder-reconcile.d.ts.map +1 -0
  348. package/dist/storage/folder-reconcile.js +65 -0
  349. package/dist/storage/folder-reconcile.js.map +1 -0
  350. package/dist/storage/index.d.ts +10 -0
  351. package/dist/storage/index.d.ts.map +1 -0
  352. package/dist/storage/index.js +9 -0
  353. package/dist/storage/index.js.map +1 -0
  354. package/dist/storage/indexeddb-adapter.d.ts +12 -0
  355. package/dist/storage/indexeddb-adapter.d.ts.map +1 -0
  356. package/dist/storage/indexeddb-adapter.js +190 -0
  357. package/dist/storage/indexeddb-adapter.js.map +1 -0
  358. package/dist/storage/mst.d.ts +121 -0
  359. package/dist/storage/mst.d.ts.map +1 -0
  360. package/dist/storage/mst.js +402 -0
  361. package/dist/storage/mst.js.map +1 -0
  362. package/dist/storage/storage-provider.d.ts +85 -0
  363. package/dist/storage/storage-provider.d.ts.map +1 -0
  364. package/dist/storage/storage-provider.js +220 -0
  365. package/dist/storage/storage-provider.js.map +1 -0
  366. package/dist/sync/anti-entropy.d.ts +49 -0
  367. package/dist/sync/anti-entropy.d.ts.map +1 -0
  368. package/dist/sync/anti-entropy.js +62 -0
  369. package/dist/sync/anti-entropy.js.map +1 -0
  370. package/dist/sync/index.d.ts +4 -0
  371. package/dist/sync/index.d.ts.map +1 -0
  372. package/dist/sync/index.js +4 -0
  373. package/dist/sync/index.js.map +1 -0
  374. package/dist/sync/sync-engine.d.ts +71 -0
  375. package/dist/sync/sync-engine.d.ts.map +1 -0
  376. package/dist/sync/sync-engine.js +309 -0
  377. package/dist/sync/sync-engine.js.map +1 -0
  378. package/dist/sync/sync-messages.d.ts +75 -0
  379. package/dist/sync/sync-messages.d.ts.map +1 -0
  380. package/dist/sync/sync-messages.js +12 -0
  381. package/dist/sync/sync-messages.js.map +1 -0
  382. package/dist/types.d.ts +243 -0
  383. package/dist/types.d.ts.map +1 -0
  384. package/dist/types.js +7 -0
  385. package/dist/types.js.map +1 -0
  386. package/dist/utils/encoding.d.ts +63 -0
  387. package/dist/utils/encoding.d.ts.map +1 -0
  388. package/dist/utils/encoding.js +130 -0
  389. package/dist/utils/encoding.js.map +1 -0
  390. package/dist/utils/errors.d.ts +43 -0
  391. package/dist/utils/errors.d.ts.map +1 -0
  392. package/dist/utils/errors.js +28 -0
  393. package/dist/utils/errors.js.map +1 -0
  394. package/dist/utils/events.d.ts +19 -0
  395. package/dist/utils/events.d.ts.map +1 -0
  396. package/dist/utils/events.js +27 -0
  397. package/dist/utils/events.js.map +1 -0
  398. package/dist/utils/hash.d.ts +23 -0
  399. package/dist/utils/hash.d.ts.map +1 -0
  400. package/dist/utils/hash.js +49 -0
  401. package/dist/utils/hash.js.map +1 -0
  402. package/dist/utils/index.d.ts +9 -0
  403. package/dist/utils/index.d.ts.map +1 -0
  404. package/dist/utils/index.js +9 -0
  405. package/dist/utils/index.js.map +1 -0
  406. package/dist/validation/capability-gate.d.ts +50 -0
  407. package/dist/validation/capability-gate.d.ts.map +1 -0
  408. package/dist/validation/capability-gate.js +71 -0
  409. package/dist/validation/capability-gate.js.map +1 -0
  410. package/dist/validation/crypto-gate.d.ts +16 -0
  411. package/dist/validation/crypto-gate.d.ts.map +1 -0
  412. package/dist/validation/crypto-gate.js +37 -0
  413. package/dist/validation/crypto-gate.js.map +1 -0
  414. package/dist/validation/index.d.ts +6 -0
  415. package/dist/validation/index.d.ts.map +1 -0
  416. package/dist/validation/index.js +6 -0
  417. package/dist/validation/index.js.map +1 -0
  418. package/dist/validation/stateful-gate.d.ts +15 -0
  419. package/dist/validation/stateful-gate.d.ts.map +1 -0
  420. package/dist/validation/stateful-gate.js +50 -0
  421. package/dist/validation/stateful-gate.js.map +1 -0
  422. package/dist/validation/structural-gate.d.ts +18 -0
  423. package/dist/validation/structural-gate.d.ts.map +1 -0
  424. package/dist/validation/structural-gate.js +54 -0
  425. package/dist/validation/structural-gate.js.map +1 -0
  426. package/dist/validation/validation-engine.d.ts +28 -0
  427. package/dist/validation/validation-engine.d.ts.map +1 -0
  428. package/dist/validation/validation-engine.js +38 -0
  429. package/dist/validation/validation-engine.js.map +1 -0
  430. package/package.json +107 -0
@@ -0,0 +1,280 @@
1
+ /**
2
+ * @module folder-adapter
3
+ * A StorageAdapter over a directory the user picked on their own disk.
4
+ *
5
+ * This is the store that escapes the origin sandbox. IndexedDB, localStorage and
6
+ * OPFS ("Origin Private File System" — the name is the specification) are all
7
+ * keyed by origin, so two deployments of the same app can never see each other's
8
+ * data. A directory handle is not: each origin asks the user for permission once
9
+ * and both end up reading the same files. That is what makes an app a *view* on
10
+ * the user's data rather than an owner of a private copy of it.
11
+ *
12
+ * The layout is meant to be legible, because the point is that the folder
13
+ * belongs to the user:
14
+ *
15
+ * ```
16
+ * <folder>/
17
+ * accounts.json who has an account here
18
+ * accounts/<id>/account.json that account's keys, locked
19
+ * accounts/<id>/stores/<name>/
20
+ * kv/<key> MST nodes, the root pointer, space records
21
+ * expressions/<cid>.json
22
+ * ```
23
+ *
24
+ * **Expressions are the truth; the MST is an index over them.** That inversion
25
+ * is what lets two origins share one folder with no locking. Every expression
26
+ * file is immutable and named by its own content hash, so concurrent writers can
27
+ * only ever add files that agree — the one genuinely mutable thing, the MST root
28
+ * pointer, is derived state that either side can rebuild. {@link reconcileFolder}
29
+ * is what rebuilds it.
30
+ */
31
+ import { utf8Encode, utf8Decode } from '../utils/encoding.js';
32
+ const EXPRESSION_SUFFIX = '.json';
33
+ /**
34
+ * Percent-encodes a storage key into a filename.
35
+ *
36
+ * Only lowercase is left unescaped, which looks excessive until you remember
37
+ * that macOS and Windows filesystems are case-insensitive by default: without
38
+ * this, the keys `space:Abc` and `space:abc` would quietly become one file and
39
+ * one of the two values would be lost.
40
+ *
41
+ * @param key A storage key
42
+ * @returns A filename safe on every filesystem, and reversible
43
+ */
44
+ function encodeKey(key) {
45
+ let out = '';
46
+ for (const byte of utf8Encode(key)) {
47
+ const char = String.fromCharCode(byte);
48
+ out += /[a-z0-9._-]/.test(char) ? char : `%${byte.toString(16).padStart(2, '0').toUpperCase()}`;
49
+ }
50
+ return out;
51
+ }
52
+ /**
53
+ * Reverses {@link encodeKey}.
54
+ * @param name A filename written by this adapter
55
+ * @returns The storage key it stands for
56
+ */
57
+ function decodeKey(name) {
58
+ const bytes = [];
59
+ for (let i = 0; i < name.length; i++) {
60
+ if (name[i] === '%') {
61
+ bytes.push(Number.parseInt(name.slice(i + 1, i + 3), 16));
62
+ i += 2;
63
+ }
64
+ else {
65
+ bytes.push(name.charCodeAt(i));
66
+ }
67
+ }
68
+ return utf8Decode(new Uint8Array(bytes));
69
+ }
70
+ /** Whether a rejection means "that file isn't there", which is usually not an error. */
71
+ function isNotFound(error) {
72
+ return error instanceof Error && error.name === 'NotFoundError';
73
+ }
74
+ /**
75
+ * Walks — and creates — a chain of subdirectories.
76
+ * @param root The directory to start from
77
+ * @param segments Path segments, already safe for a filename
78
+ * @returns The directory at the end of the path
79
+ */
80
+ async function resolvePath(root, segments) {
81
+ let current = root;
82
+ for (const segment of segments) {
83
+ current = await current.getDirectoryHandle(segment, { create: true });
84
+ }
85
+ return current;
86
+ }
87
+ /**
88
+ * Reads a file, treating absence as null rather than as a failure.
89
+ * @param dir The directory holding it
90
+ * @param name The filename
91
+ * @returns Its bytes, or null when there is no such file
92
+ */
93
+ export async function readFolderFile(dir, name) {
94
+ try {
95
+ const handle = await dir.getFileHandle(name);
96
+ const file = await handle.getFile();
97
+ return new Uint8Array(await file.arrayBuffer());
98
+ }
99
+ catch (error) {
100
+ if (isNotFound(error))
101
+ return null;
102
+ throw error;
103
+ }
104
+ }
105
+ /**
106
+ * Writes a file, replacing whatever was there.
107
+ * @param dir The directory to write into
108
+ * @param name The filename
109
+ * @param bytes The contents
110
+ */
111
+ export async function writeFolderFile(dir, name, bytes) {
112
+ const handle = await dir.getFileHandle(name, { create: true });
113
+ const writable = await handle.createWritable();
114
+ await writable.write(bytes);
115
+ await writable.close();
116
+ }
117
+ /**
118
+ * Deletes a file, ignoring one that is already gone.
119
+ * @param dir The directory holding it
120
+ * @param name The filename
121
+ */
122
+ async function removeFile(dir, name) {
123
+ try {
124
+ await dir.removeEntry(name);
125
+ }
126
+ catch (error) {
127
+ if (!isNotFound(error))
128
+ throw error;
129
+ }
130
+ }
131
+ /**
132
+ * Opens a storage adapter backed by a directory on the user's disk.
133
+ *
134
+ * Expressions are held in memory as well as on disk — a query would otherwise
135
+ * mean one file read per record, and the example app re-lists on every render.
136
+ * The cost is that the working set has to fit in memory.
137
+ *
138
+ * @param root The directory the user picked
139
+ * @param path Where to keep these files inside it, `/` separating
140
+ * subdirectories. The full path from the folder root, so that several
141
+ * accounts can each have a subtree of their own.
142
+ * @returns An adapter over that directory, already populated
143
+ */
144
+ export async function createFolderAdapter(root, path) {
145
+ const segments = path.split('/').filter(Boolean).map(encodeKey);
146
+ if (segments.length === 0) {
147
+ throw new Error('A folder adapter needs a path to live in.');
148
+ }
149
+ const base = await resolvePath(root, segments);
150
+ const kvDir = await base.getDirectoryHandle('kv', { create: true });
151
+ const expressionsDir = await base.getDirectoryHandle('expressions', { create: true });
152
+ const expressions = new Map();
153
+ // Content-addressed nodes never change, so caching them is free. The root
154
+ // pointer does change, which is why `reload` throws the whole cache away
155
+ // rather than trying to be clever about which entries are still good.
156
+ const kvCache = new Map();
157
+ async function readExpressionFile(name) {
158
+ const bytes = await readFolderFile(expressionsDir, name);
159
+ if (!bytes)
160
+ return null;
161
+ try {
162
+ return JSON.parse(utf8Decode(bytes));
163
+ }
164
+ catch {
165
+ // A half-written file from a writer that died mid-flush. It will either be
166
+ // rewritten or stay unreadable; either way it is not ours to repair.
167
+ return null;
168
+ }
169
+ }
170
+ async function reload() {
171
+ const seen = new Set();
172
+ const added = [];
173
+ for await (const name of expressionsDir.keys()) {
174
+ if (!name.endsWith(EXPRESSION_SUFFIX))
175
+ continue;
176
+ const id = decodeKey(name.slice(0, -EXPRESSION_SUFFIX.length));
177
+ seen.add(id);
178
+ if (expressions.has(id))
179
+ continue;
180
+ const expression = await readExpressionFile(name);
181
+ if (!expression)
182
+ continue;
183
+ expressions.set(id, expression);
184
+ added.push(id);
185
+ }
186
+ const removed = [...expressions.keys()].filter((id) => !seen.has(id));
187
+ for (const id of removed)
188
+ expressions.delete(id);
189
+ kvCache.clear();
190
+ return { added, removed };
191
+ }
192
+ await reload();
193
+ return Object.freeze({
194
+ namespace: path,
195
+ reload,
196
+ async listExpressionIds() {
197
+ return [...expressions.keys()];
198
+ },
199
+ async get(key) {
200
+ const cached = kvCache.get(key);
201
+ if (cached !== undefined)
202
+ return cached;
203
+ const bytes = await readFolderFile(kvDir, encodeKey(key));
204
+ kvCache.set(key, bytes);
205
+ return bytes;
206
+ },
207
+ async put(key, value) {
208
+ await writeFolderFile(kvDir, encodeKey(key), value);
209
+ kvCache.set(key, value);
210
+ },
211
+ async delete(key) {
212
+ await removeFile(kvDir, encodeKey(key));
213
+ kvCache.set(key, null);
214
+ },
215
+ async has(key) {
216
+ const cached = kvCache.get(key);
217
+ if (cached !== undefined)
218
+ return cached !== null;
219
+ return (await readFolderFile(kvDir, encodeKey(key))) !== null;
220
+ },
221
+ async list(prefix = '') {
222
+ const keys = [];
223
+ for await (const name of kvDir.keys()) {
224
+ const key = decodeKey(name);
225
+ if (!key.startsWith(prefix))
226
+ continue;
227
+ keys.push(key);
228
+ // Another writer created it after this process looked and found
229
+ // nothing. The file is on disk now, so the remembered miss is stale.
230
+ if (kvCache.get(key) === null)
231
+ kvCache.delete(key);
232
+ }
233
+ return keys;
234
+ },
235
+ async queryExpressions(collection, limit = 50, cursor) {
236
+ // Ordered so a cursor means the same thing on every device, which a
237
+ // directory listing on its own would not guarantee.
238
+ const ordered = [...expressions.values()]
239
+ .filter((expression) => expression.collection === collection)
240
+ .sort((a, b) => a.createdAt.localeCompare(b.createdAt) || a.id.localeCompare(b.id));
241
+ const start = cursor ? ordered.findIndex((expression) => expression.id === cursor) + 1 : 0;
242
+ return ordered.slice(start, start + limit);
243
+ },
244
+ async putExpression(expression) {
245
+ await writeFolderFile(expressionsDir, encodeKey(expression.id) + EXPRESSION_SUFFIX, utf8Encode(JSON.stringify(expression)));
246
+ expressions.set(expression.id, expression);
247
+ },
248
+ async getExpression(id) {
249
+ const known = expressions.get(id);
250
+ if (known)
251
+ return known;
252
+ // Not in memory: another origin may have written it since the last reload.
253
+ const expression = await readExpressionFile(encodeKey(id) + EXPRESSION_SUFFIX);
254
+ if (expression)
255
+ expressions.set(id, expression);
256
+ return expression;
257
+ },
258
+ async deleteExpression(id) {
259
+ await removeFile(expressionsDir, encodeKey(id) + EXPRESSION_SUFFIX);
260
+ expressions.delete(id);
261
+ },
262
+ async batch(ops) {
263
+ for (const op of ops) {
264
+ if (op.type === 'put') {
265
+ await writeFolderFile(kvDir, encodeKey(op.key), op.value);
266
+ kvCache.set(op.key, op.value);
267
+ }
268
+ else {
269
+ await removeFile(kvDir, encodeKey(op.key));
270
+ kvCache.set(op.key, null);
271
+ }
272
+ }
273
+ },
274
+ async close() {
275
+ expressions.clear();
276
+ kvCache.clear();
277
+ },
278
+ });
279
+ }
280
+ //# sourceMappingURL=folder-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folder-adapter.js","sourceRoot":"","sources":["../../src/storage/folder-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @module folder-reconcile
3
+ * Making a shared folder converge, without anybody having to take a lock.
4
+ *
5
+ * Two origins — or two devices behind Dropbox, iCloud or Syncthing — can write
6
+ * into one folder at the same time. Almost nothing there can actually conflict:
7
+ * expression files are named by their own content hash, so two writers either
8
+ * produce different files or produce byte-identical ones. The single mutable
9
+ * thing is the MST root pointer, and a lost write to it costs nothing, because
10
+ * the tree is derived state.
11
+ *
12
+ * So the rule is: **the set of expression files wins.** Reconciling means
13
+ * rebuilding the tree until it agrees with the directory — adding what turned up
14
+ * and dropping what went away. That is the whole concurrency story.
15
+ */
16
+ import type { StorageProvider } from './storage-provider.js';
17
+ import type { FolderAdapter } from './folder-adapter.js';
18
+ import type { Expression } from '../types.js';
19
+ /** What a pass over the folder found */
20
+ export interface FolderReconciliation {
21
+ /** Expression files that appeared since the last pass — another origin's writes */
22
+ readonly added: ReadonlyArray<string>;
23
+ /** Expression files that are gone */
24
+ readonly removed: ReadonlyArray<string>;
25
+ /**
26
+ * Tree entries that had to be fixed to match the directory.
27
+ *
28
+ * Usually empty, and that is the expected case rather than a lucky one: both
29
+ * origins read and write the same root pointer, so the tree one of them built
30
+ * is normally already right for the other. This fills in when a pointer write
31
+ * was lost — two writers racing, or a folder that came back from Dropbox with
32
+ * files the pointer never saw.
33
+ */
34
+ readonly repaired: ReadonlyArray<string>;
35
+ /** Whether anything moved at all — worth a re-render when true */
36
+ readonly changed: boolean;
37
+ }
38
+ /**
39
+ * Re-reads the folder and brings the Merkle tree back in line with it.
40
+ *
41
+ * Safe to call as often as you like: with nothing new on disk it is two
42
+ * directory listings and no writes.
43
+ *
44
+ * @param storage The provider whose tree should be brought up to date
45
+ * @param adapter The folder adapter underneath it
46
+ * @param accept Whether a version found on disk may be placed. Anyone who can
47
+ * write the folder can drop a file in it — another site given the folder, a
48
+ * sync service — so what turns up there is checked like anything arriving
49
+ * from a peer. A version refused now stays on disk and is asked about again.
50
+ * @returns What moved
51
+ */
52
+ export declare function reconcileFolder(storage: StorageProvider, adapter: FolderAdapter, accept?: (expression: Expression) => Promise<boolean>): Promise<FolderReconciliation>;
53
+ //# sourceMappingURL=folder-reconcile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folder-reconcile.d.ts","sourceRoot":"","sources":["../../src/storage/folder-reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,wCAAwC;AACxC,MAAM,WAAW,oBAAoB;IACnC,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,qCAAqC;IACrC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;;;;OAQG;IACH,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,aAAa,EACtB,MAAM,GAAE,CAAC,UAAU,EAAE,UAAU,KAAK,OAAO,CAAC,OAAO,CAAoB,GACtE,OAAO,CAAC,oBAAoB,CAAC,CAoC/B"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @module folder-reconcile
3
+ * Making a shared folder converge, without anybody having to take a lock.
4
+ *
5
+ * Two origins — or two devices behind Dropbox, iCloud or Syncthing — can write
6
+ * into one folder at the same time. Almost nothing there can actually conflict:
7
+ * expression files are named by their own content hash, so two writers either
8
+ * produce different files or produce byte-identical ones. The single mutable
9
+ * thing is the MST root pointer, and a lost write to it costs nothing, because
10
+ * the tree is derived state.
11
+ *
12
+ * So the rule is: **the set of expression files wins.** Reconciling means
13
+ * rebuilding the tree until it agrees with the directory — adding what turned up
14
+ * and dropping what went away. That is the whole concurrency story.
15
+ */
16
+ /**
17
+ * Re-reads the folder and brings the Merkle tree back in line with it.
18
+ *
19
+ * Safe to call as often as you like: with nothing new on disk it is two
20
+ * directory listings and no writes.
21
+ *
22
+ * @param storage The provider whose tree should be brought up to date
23
+ * @param adapter The folder adapter underneath it
24
+ * @param accept Whether a version found on disk may be placed. Anyone who can
25
+ * write the folder can drop a file in it — another site given the folder, a
26
+ * sync service — so what turns up there is checked like anything arriving
27
+ * from a peer. A version refused now stays on disk and is asked about again.
28
+ * @returns What moved
29
+ */
30
+ export async function reconcileFolder(storage, adapter, accept = async () => true) {
31
+ const disk = await adapter.reload();
32
+ const onDisk = new Set(await adapter.listExpressionIds());
33
+ // Versions another writer put on disk that this tree has not placed. Each
34
+ // goes through the ordering rule like anything else: it becomes current,
35
+ // is kept as history, or loses and is dropped — the same decision the other
36
+ // writer reached, so both converge on the same tree.
37
+ const indexed = new Set((await storage.entries()).map((entry) => entry.value));
38
+ const missing = [...onDisk].filter((id) => !indexed.has(id));
39
+ const placed = [];
40
+ for (const id of missing) {
41
+ const expression = await adapter.getExpression(id);
42
+ // A file can vanish between the listing and the read — another writer
43
+ // dropping a superseded version. Nothing to add, and the next pass agrees.
44
+ if (expression && (await accept(expression))) {
45
+ await storage.addExpression(expression);
46
+ placed.push(id);
47
+ }
48
+ }
49
+ // Entries whose file is gone: another writer superseded and dropped it, and
50
+ // its replacement was placed above.
51
+ const stale = [...new Set((await storage.entries()).map((entry) => entry.value))].filter((id) => !onDisk.has(id) && !missing.includes(id));
52
+ for (const id of stale) {
53
+ if (!(await adapter.getExpression(id)))
54
+ await storage.removeExpression(id);
55
+ }
56
+ // A refused file is not a change: it would otherwise redraw every pass.
57
+ const repaired = [...placed, ...stale];
58
+ return {
59
+ added: disk.added,
60
+ removed: disk.removed,
61
+ repaired,
62
+ changed: disk.added.length > 0 || disk.removed.length > 0 || repaired.length > 0,
63
+ };
64
+ }
65
+ //# sourceMappingURL=folder-reconcile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folder-reconcile.js","sourceRoot":"","sources":["../../src/storage/folder-reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA0BH;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAwB,EACxB,OAAsB,EACtB,SAAuD,KAAK,IAAI,EAAE,CAAC,IAAI;IAEvE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAE1D,0EAA0E;IAC1E,yEAAyE;IACzE,4EAA4E;IAC5E,qDAAqD;IACrD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/E,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QACnD,sEAAsE;QACtE,2EAA2E;QAC3E,IAAI,UAAU,IAAI,CAAC,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YAC7C,MAAM,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,oCAAoC;IACpC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3I,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,wEAAwE;IACxE,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC;IACvC,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ;QACR,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;KACjF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @module storage
3
+ * Exports all storage related functionality.
4
+ */
5
+ export * from './indexeddb-adapter.js';
6
+ export * from './mst.js';
7
+ export * from './storage-provider.js';
8
+ export * from './directory-access.js';
9
+ export type { DirectoryHandleLike } from './folder-adapter.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,wBAAwB,CAAC;AACvC,cAAc,UAAU,CAAC;AACzB,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @module storage
3
+ * Exports all storage related functionality.
4
+ */
5
+ export * from './indexeddb-adapter.js';
6
+ export * from './mst.js';
7
+ export * from './storage-provider.js';
8
+ export * from './directory-access.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,wBAAwB,CAAC;AACvC,cAAc,UAAU,CAAC;AACzB,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @module indexeddb-adapter
3
+ * IndexedDB implementation of StorageAdapter for P2P network.
4
+ */
5
+ import type { StorageAdapter } from '../types.js';
6
+ /**
7
+ * Creates an IndexedDB backed storage adapter.
8
+ * @param dbName The name of the database (defaults to 'weave-storage')
9
+ * @returns A promise resolving to the StorageAdapter
10
+ */
11
+ export declare function createIndexedDBAdapter(dbName?: string): Promise<StorageAdapter>;
12
+ //# sourceMappingURL=indexeddb-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexeddb-adapter.d.ts","sourceRoot":"","sources":["../../src/storage/indexeddb-adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAC;AAyCvE;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,MAAM,GAAE,MAAwB,GAAG,OAAO,CAAC,cAAc,CAAC,CAuKtG"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * @module indexeddb-adapter
3
+ * IndexedDB implementation of StorageAdapter for P2P network.
4
+ */
5
+ /**
6
+ * Bumped to 2 when MST nodes gained a `height` field. Opening an older
7
+ * database wipes it rather than reading nodes the tree can no longer parse.
8
+ */
9
+ const DB_VERSION = 2;
10
+ /**
11
+ * Promisify an IDBRequest.
12
+ * @param request The IDBRequest to promisify
13
+ * @returns A promise that resolves with the request result
14
+ */
15
+ function idbRequest(request) {
16
+ return new Promise((resolve, reject) => {
17
+ request.onsuccess = () => resolve(request.result);
18
+ request.onerror = () => reject(request.error);
19
+ });
20
+ }
21
+ /**
22
+ * Helper to manage IDBTransactions.
23
+ * @param db The IDB database instance
24
+ * @param stores The stores to include in the transaction
25
+ * @param mode The transaction mode ('readonly' | 'readwrite')
26
+ * @returns The transaction and a promise that resolves when it completes
27
+ */
28
+ function idbTransaction(db, stores, mode) {
29
+ const tx = db.transaction(stores, mode);
30
+ const complete = new Promise((resolve, reject) => {
31
+ tx.oncomplete = () => resolve();
32
+ tx.onerror = () => reject(tx.error);
33
+ tx.onabort = () => reject(new Error('Transaction aborted'));
34
+ });
35
+ return { tx, complete };
36
+ }
37
+ /**
38
+ * Creates an IndexedDB backed storage adapter.
39
+ * @param dbName The name of the database (defaults to 'weave-storage')
40
+ * @returns A promise resolving to the StorageAdapter
41
+ */
42
+ export async function createIndexedDBAdapter(dbName = 'weave-storage') {
43
+ const db = await new Promise((resolve, reject) => {
44
+ const request = globalThis.indexedDB.open(dbName, DB_VERSION);
45
+ request.onupgradeneeded = (event) => {
46
+ const db = request.result;
47
+ const previousVersion = event.oldVersion;
48
+ // v1 stored MST nodes without a height, which the current tree cannot
49
+ // read. There is no way to migrate them — the old structure was a single
50
+ // flat node with no tree to recover — so the local cache is dropped and
51
+ // rebuilt by syncing with peers.
52
+ if (previousVersion > 0 && previousVersion < 2) {
53
+ for (const name of ['kv', 'expressions']) {
54
+ if (db.objectStoreNames.contains(name))
55
+ db.deleteObjectStore(name);
56
+ }
57
+ }
58
+ // Store for key-value (MST nodes, root cid, etc)
59
+ if (!db.objectStoreNames.contains('kv')) {
60
+ db.createObjectStore('kv');
61
+ }
62
+ // Store for expressions
63
+ if (!db.objectStoreNames.contains('expressions')) {
64
+ const expStore = db.createObjectStore('expressions', { keyPath: 'id' });
65
+ expStore.createIndex('collection', 'collection', { unique: false });
66
+ expStore.createIndex('author', 'author', { unique: false });
67
+ expStore.createIndex('createdAt', 'createdAt', { unique: false });
68
+ }
69
+ };
70
+ request.onsuccess = () => resolve(request.result);
71
+ request.onerror = () => reject(request.error);
72
+ });
73
+ return Object.freeze({
74
+ async get(key) {
75
+ const { tx } = idbTransaction(db, ['kv'], 'readonly');
76
+ const store = tx.objectStore('kv');
77
+ const result = await idbRequest(store.get(key));
78
+ return result ? new Uint8Array(result) : null;
79
+ },
80
+ async put(key, value) {
81
+ const { tx, complete } = idbTransaction(db, ['kv'], 'readwrite');
82
+ const store = tx.objectStore('kv');
83
+ store.put(value.buffer, key);
84
+ await complete;
85
+ },
86
+ async delete(key) {
87
+ const { tx, complete } = idbTransaction(db, ['kv'], 'readwrite');
88
+ const store = tx.objectStore('kv');
89
+ store.delete(key);
90
+ await complete;
91
+ },
92
+ async has(key) {
93
+ const { tx } = idbTransaction(db, ['kv'], 'readonly');
94
+ const store = tx.objectStore('kv');
95
+ const count = await idbRequest(store.count(key));
96
+ return count > 0;
97
+ },
98
+ async list(prefix = '') {
99
+ const { tx } = idbTransaction(db, ['kv'], 'readonly');
100
+ const store = tx.objectStore('kv');
101
+ const keys = [];
102
+ let request;
103
+ if (prefix) {
104
+ const bound = prefix + '\uFFFF';
105
+ request = store.openCursor(IDBKeyRange.bound(prefix, bound, false, false));
106
+ }
107
+ else {
108
+ request = store.openCursor();
109
+ }
110
+ await new Promise((resolve, reject) => {
111
+ request.onsuccess = (event) => {
112
+ const cursor = event.target.result;
113
+ if (cursor) {
114
+ keys.push(cursor.key);
115
+ cursor.continue();
116
+ }
117
+ else {
118
+ resolve();
119
+ }
120
+ };
121
+ request.onerror = () => reject(request.error);
122
+ });
123
+ return keys;
124
+ },
125
+ async queryExpressions(collection, limit = 50, cursor) {
126
+ const { tx } = idbTransaction(db, ['expressions'], 'readonly');
127
+ const store = tx.objectStore('expressions');
128
+ const index = store.index('collection');
129
+ const range = IDBKeyRange.only(collection);
130
+ const request = index.openCursor(range);
131
+ const results = [];
132
+ let advanced = !cursor;
133
+ await new Promise((resolve, reject) => {
134
+ request.onsuccess = (event) => {
135
+ const idbCursor = event.target.result;
136
+ if (!idbCursor || results.length >= limit) {
137
+ resolve();
138
+ return;
139
+ }
140
+ if (!advanced && cursor && idbCursor.primaryKey === cursor) {
141
+ advanced = true;
142
+ idbCursor.continue();
143
+ return;
144
+ }
145
+ if (advanced) {
146
+ results.push(idbCursor.value);
147
+ }
148
+ idbCursor.continue();
149
+ };
150
+ request.onerror = () => reject(request.error);
151
+ });
152
+ return results;
153
+ },
154
+ async putExpression(expression) {
155
+ const { tx, complete } = idbTransaction(db, ['expressions'], 'readwrite');
156
+ const store = tx.objectStore('expressions');
157
+ store.put(expression);
158
+ await complete;
159
+ },
160
+ async getExpression(id) {
161
+ const { tx } = idbTransaction(db, ['expressions'], 'readonly');
162
+ const store = tx.objectStore('expressions');
163
+ const result = await idbRequest(store.get(id));
164
+ return result || null;
165
+ },
166
+ async deleteExpression(id) {
167
+ const { tx, complete } = idbTransaction(db, ['expressions'], 'readwrite');
168
+ const store = tx.objectStore('expressions');
169
+ store.delete(id);
170
+ await complete;
171
+ },
172
+ async batch(ops) {
173
+ const { tx, complete } = idbTransaction(db, ['kv'], 'readwrite');
174
+ const store = tx.objectStore('kv');
175
+ for (const op of ops) {
176
+ if (op.type === 'put') {
177
+ store.put(op.value.buffer, op.key);
178
+ }
179
+ else if (op.type === 'delete') {
180
+ store.delete(op.key);
181
+ }
182
+ }
183
+ await complete;
184
+ },
185
+ async close() {
186
+ db.close();
187
+ }
188
+ });
189
+ }
190
+ //# sourceMappingURL=indexeddb-adapter.js.map