@earendil-works/chord 1.4.0 → 1.5.1

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 (1299) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/README.md +115 -90
  3. package/dist/context/index.d.ts +1 -1
  4. package/dist/context/index.d.ts.map +1 -1
  5. package/dist/context/index.js +1 -1
  6. package/dist/context/index.js.map +1 -1
  7. package/dist/contracts/accepts.d.ts +81 -0
  8. package/dist/contracts/accepts.d.ts.map +1 -0
  9. package/dist/contracts/accepts.js +123 -0
  10. package/dist/contracts/accepts.js.map +1 -0
  11. package/dist/contracts/contract.d.ts +121 -0
  12. package/dist/contracts/contract.d.ts.map +1 -0
  13. package/dist/contracts/contract.js +50 -0
  14. package/dist/contracts/contract.js.map +1 -0
  15. package/dist/contracts/declare.d.ts +107 -0
  16. package/dist/contracts/declare.d.ts.map +1 -0
  17. package/dist/contracts/declare.js +136 -0
  18. package/dist/contracts/declare.js.map +1 -0
  19. package/dist/contracts/evolve.d.ts +92 -0
  20. package/dist/contracts/evolve.d.ts.map +1 -0
  21. package/dist/contracts/evolve.js +179 -0
  22. package/dist/contracts/evolve.js.map +1 -0
  23. package/dist/contracts/fingerprint.d.ts +16 -0
  24. package/dist/contracts/fingerprint.d.ts.map +1 -0
  25. package/dist/contracts/fingerprint.js +50 -0
  26. package/dist/contracts/fingerprint.js.map +1 -0
  27. package/dist/contracts/history.d.ts +71 -0
  28. package/dist/contracts/history.d.ts.map +1 -0
  29. package/dist/contracts/history.js +3 -0
  30. package/dist/contracts/history.js.map +1 -0
  31. package/dist/contracts/host-kind.d.ts +40 -0
  32. package/dist/contracts/host-kind.d.ts.map +1 -0
  33. package/dist/contracts/host-kind.js +37 -0
  34. package/dist/contracts/host-kind.js.map +1 -0
  35. package/dist/contracts/index.d.ts +7 -0
  36. package/dist/contracts/index.d.ts.map +1 -0
  37. package/dist/contracts/index.js +6 -0
  38. package/dist/contracts/index.js.map +1 -0
  39. package/dist/contracts/internal.d.ts +10 -0
  40. package/dist/contracts/internal.d.ts.map +1 -0
  41. package/dist/contracts/internal.js +9 -0
  42. package/dist/contracts/internal.js.map +1 -0
  43. package/dist/contracts/names.d.ts +3 -0
  44. package/dist/contracts/names.d.ts.map +1 -0
  45. package/dist/contracts/names.js +13 -0
  46. package/dist/contracts/names.js.map +1 -0
  47. package/dist/contracts/params.d.ts +28 -0
  48. package/dist/contracts/params.d.ts.map +1 -0
  49. package/dist/contracts/params.js +50 -0
  50. package/dist/contracts/params.js.map +1 -0
  51. package/dist/contracts/schema.d.ts +102 -0
  52. package/dist/contracts/schema.d.ts.map +1 -0
  53. package/dist/contracts/schema.js +103 -0
  54. package/dist/contracts/schema.js.map +1 -0
  55. package/dist/contracts/snapshot.d.ts +16 -0
  56. package/dist/contracts/snapshot.d.ts.map +1 -0
  57. package/dist/contracts/snapshot.js +167 -0
  58. package/dist/contracts/snapshot.js.map +1 -0
  59. package/dist/data/args.d.ts +50 -0
  60. package/dist/data/args.d.ts.map +1 -0
  61. package/dist/data/args.js +83 -0
  62. package/dist/data/args.js.map +1 -0
  63. package/dist/data/errors.d.ts +80 -0
  64. package/dist/data/errors.d.ts.map +1 -0
  65. package/dist/data/errors.js +116 -0
  66. package/dist/data/errors.js.map +1 -0
  67. package/dist/data/failure.d.ts +26 -0
  68. package/dist/data/failure.d.ts.map +1 -0
  69. package/dist/data/failure.js +77 -0
  70. package/dist/data/failure.js.map +1 -0
  71. package/dist/data/index.d.ts +4 -0
  72. package/dist/data/index.d.ts.map +1 -0
  73. package/dist/data/index.js +5 -0
  74. package/dist/data/index.js.map +1 -0
  75. package/dist/data/internal.d.ts +7 -0
  76. package/dist/data/internal.d.ts.map +1 -0
  77. package/dist/data/internal.js +8 -0
  78. package/dist/data/internal.js.map +1 -0
  79. package/dist/data/params.d.ts +20 -0
  80. package/dist/data/params.d.ts.map +1 -0
  81. package/dist/data/params.js +31 -0
  82. package/dist/data/params.js.map +1 -0
  83. package/dist/data/principal.d.ts +22 -0
  84. package/dist/data/principal.d.ts.map +1 -0
  85. package/dist/data/principal.js +49 -0
  86. package/dist/data/principal.js.map +1 -0
  87. package/dist/data/validator.d.ts +12 -0
  88. package/dist/data/validator.d.ts.map +1 -0
  89. package/dist/data/validator.js +35 -0
  90. package/dist/data/validator.js.map +1 -0
  91. package/dist/delta/apply-immutable-trusted.js +3 -4
  92. package/dist/delta/apply-immutable-trusted.js.map +1 -1
  93. package/dist/delta/diff.d.ts.map +1 -1
  94. package/dist/delta/diff.js +5 -3
  95. package/dist/delta/diff.js.map +1 -1
  96. package/dist/delta/index.d.ts +9 -1
  97. package/dist/delta/index.d.ts.map +1 -1
  98. package/dist/delta/index.js +15 -11
  99. package/dist/delta/index.js.map +1 -1
  100. package/dist/delta/pending.d.ts +36 -0
  101. package/dist/delta/pending.d.ts.map +1 -0
  102. package/dist/delta/pending.js +143 -0
  103. package/dist/delta/pending.js.map +1 -0
  104. package/dist/delta/tracker.d.ts +12 -0
  105. package/dist/delta/tracker.d.ts.map +1 -1
  106. package/dist/delta/tracker.js +109 -39
  107. package/dist/delta/tracker.js.map +1 -1
  108. package/dist/documents/address-source.d.ts +20 -0
  109. package/dist/documents/address-source.d.ts.map +1 -0
  110. package/dist/documents/address-source.js +44 -0
  111. package/dist/documents/address-source.js.map +1 -0
  112. package/dist/documents/definition.d.ts +84 -0
  113. package/dist/documents/definition.d.ts.map +1 -0
  114. package/dist/documents/definition.js +74 -0
  115. package/dist/documents/definition.js.map +1 -0
  116. package/dist/documents/documents.d.ts +126 -0
  117. package/dist/documents/documents.d.ts.map +1 -0
  118. package/dist/documents/documents.js +248 -0
  119. package/dist/documents/documents.js.map +1 -0
  120. package/dist/documents/fence.d.ts +9 -0
  121. package/dist/documents/fence.d.ts.map +1 -0
  122. package/dist/documents/fence.js +15 -0
  123. package/dist/documents/fence.js.map +1 -0
  124. package/dist/documents/handles.d.ts +76 -0
  125. package/dist/documents/handles.d.ts.map +1 -0
  126. package/dist/documents/handles.js +66 -0
  127. package/dist/documents/handles.js.map +1 -0
  128. package/dist/documents/index.d.ts +4 -0
  129. package/dist/documents/index.d.ts.map +1 -0
  130. package/dist/documents/index.js +3 -0
  131. package/dist/documents/index.js.map +1 -0
  132. package/dist/documents/internal.d.ts +9 -0
  133. package/dist/documents/internal.d.ts.map +1 -0
  134. package/dist/documents/internal.js +9 -0
  135. package/dist/documents/internal.js.map +1 -0
  136. package/dist/documents/keyed-slot.d.ts +103 -0
  137. package/dist/documents/keyed-slot.d.ts.map +1 -0
  138. package/dist/documents/keyed-slot.js +395 -0
  139. package/dist/documents/keyed-slot.js.map +1 -0
  140. package/dist/documents/line.d.ts +7 -0
  141. package/dist/documents/line.d.ts.map +1 -0
  142. package/dist/documents/line.js +14 -0
  143. package/dist/documents/line.js.map +1 -0
  144. package/dist/documents/persistence.d.ts +104 -0
  145. package/dist/documents/persistence.d.ts.map +1 -0
  146. package/dist/documents/persistence.js +129 -0
  147. package/dist/documents/persistence.js.map +1 -0
  148. package/dist/documents/residency.d.ts +31 -0
  149. package/dist/documents/residency.d.ts.map +1 -0
  150. package/dist/documents/residency.js +93 -0
  151. package/dist/documents/residency.js.map +1 -0
  152. package/dist/documents/slot.d.ts +109 -0
  153. package/dist/documents/slot.d.ts.map +1 -0
  154. package/dist/documents/slot.js +181 -0
  155. package/dist/documents/slot.js.map +1 -0
  156. package/dist/documents/transaction.d.ts +143 -0
  157. package/dist/documents/transaction.d.ts.map +1 -0
  158. package/dist/documents/transaction.js +442 -0
  159. package/dist/documents/transaction.js.map +1 -0
  160. package/dist/host/activity.d.ts +31 -0
  161. package/dist/host/activity.d.ts.map +1 -0
  162. package/dist/host/activity.js +40 -0
  163. package/dist/host/activity.js.map +1 -0
  164. package/dist/host/adapted.d.ts +49 -0
  165. package/dist/host/adapted.d.ts.map +1 -0
  166. package/dist/host/adapted.js +214 -0
  167. package/dist/host/adapted.js.map +1 -0
  168. package/dist/host/attempt.d.ts +308 -0
  169. package/dist/host/attempt.d.ts.map +1 -0
  170. package/dist/host/attempt.js +1199 -0
  171. package/dist/host/attempt.js.map +1 -0
  172. package/dist/host/backoff.d.ts +29 -0
  173. package/dist/host/backoff.d.ts.map +1 -0
  174. package/dist/host/backoff.js +69 -0
  175. package/dist/host/backoff.js.map +1 -0
  176. package/dist/host/ctx.d.ts +94 -0
  177. package/dist/host/ctx.d.ts.map +1 -0
  178. package/dist/host/ctx.js +200 -0
  179. package/dist/host/ctx.js.map +1 -0
  180. package/dist/host/deadline.d.ts +12 -0
  181. package/dist/host/deadline.d.ts.map +1 -0
  182. package/dist/host/deadline.js +40 -0
  183. package/dist/host/deadline.js.map +1 -0
  184. package/dist/host/dependencies.d.ts +65 -0
  185. package/dist/host/dependencies.d.ts.map +1 -0
  186. package/dist/host/dependencies.js +115 -0
  187. package/dist/host/dependencies.js.map +1 -0
  188. package/dist/host/destination.d.ts +48 -0
  189. package/dist/host/destination.d.ts.map +1 -0
  190. package/dist/host/destination.js +101 -0
  191. package/dist/host/destination.js.map +1 -0
  192. package/dist/host/facet.d.ts +84 -0
  193. package/dist/host/facet.d.ts.map +1 -0
  194. package/dist/host/facet.js +55 -0
  195. package/dist/host/facet.js.map +1 -0
  196. package/dist/host/follow.d.ts +52 -0
  197. package/dist/host/follow.d.ts.map +1 -0
  198. package/dist/host/follow.js +207 -0
  199. package/dist/host/follow.js.map +1 -0
  200. package/dist/host/host.d.ts +571 -0
  201. package/dist/host/host.d.ts.map +1 -0
  202. package/dist/host/host.js +1318 -0
  203. package/dist/host/host.js.map +1 -0
  204. package/dist/host/index.d.ts +17 -0
  205. package/dist/host/index.d.ts.map +1 -0
  206. package/dist/host/index.js +6 -0
  207. package/dist/host/index.js.map +1 -0
  208. package/dist/host/internal.d.ts +11 -0
  209. package/dist/host/internal.d.ts.map +1 -0
  210. package/dist/host/internal.js +9 -0
  211. package/dist/host/internal.js.map +1 -0
  212. package/dist/host/members.d.ts +50 -0
  213. package/dist/host/members.d.ts.map +1 -0
  214. package/dist/host/members.js +107 -0
  215. package/dist/host/members.js.map +1 -0
  216. package/dist/host/native.d.ts +64 -0
  217. package/dist/host/native.d.ts.map +1 -0
  218. package/dist/host/native.js +126 -0
  219. package/dist/host/native.js.map +1 -0
  220. package/dist/host/object.d.ts +331 -0
  221. package/dist/host/object.d.ts.map +1 -0
  222. package/dist/host/object.js +1296 -0
  223. package/dist/host/object.js.map +1 -0
  224. package/dist/host/old-work.d.ts +34 -0
  225. package/dist/host/old-work.d.ts.map +1 -0
  226. package/dist/host/old-work.js +52 -0
  227. package/dist/host/old-work.js.map +1 -0
  228. package/dist/host/parked.d.ts +23 -0
  229. package/dist/host/parked.d.ts.map +1 -0
  230. package/dist/host/parked.js +79 -0
  231. package/dist/host/parked.js.map +1 -0
  232. package/dist/host/presence.d.ts +34 -0
  233. package/dist/host/presence.d.ts.map +1 -0
  234. package/dist/host/presence.js +117 -0
  235. package/dist/host/presence.js.map +1 -0
  236. package/dist/host/readiness.d.ts +27 -0
  237. package/dist/host/readiness.d.ts.map +1 -0
  238. package/dist/host/readiness.js +134 -0
  239. package/dist/host/readiness.js.map +1 -0
  240. package/dist/host/ref-state.d.ts +53 -0
  241. package/dist/host/ref-state.d.ts.map +1 -0
  242. package/dist/host/ref-state.js +83 -0
  243. package/dist/host/ref-state.js.map +1 -0
  244. package/dist/host/reference-keys.d.ts +36 -0
  245. package/dist/host/reference-keys.d.ts.map +1 -0
  246. package/dist/host/reference-keys.js +168 -0
  247. package/dist/host/reference-keys.js.map +1 -0
  248. package/dist/host/reference-source.d.ts +65 -0
  249. package/dist/host/reference-source.d.ts.map +1 -0
  250. package/dist/host/reference-source.js +285 -0
  251. package/dist/host/reference-source.js.map +1 -0
  252. package/dist/host/reference.d.ts +321 -0
  253. package/dist/host/reference.d.ts.map +1 -0
  254. package/dist/host/reference.js +797 -0
  255. package/dist/host/reference.js.map +1 -0
  256. package/dist/host/reload-cycle.d.ts +16 -0
  257. package/dist/host/reload-cycle.d.ts.map +1 -0
  258. package/dist/host/reload-cycle.js +81 -0
  259. package/dist/host/reload-cycle.js.map +1 -0
  260. package/dist/host/retry-on.d.ts +28 -0
  261. package/dist/host/retry-on.d.ts.map +1 -0
  262. package/dist/host/retry-on.js +52 -0
  263. package/dist/host/retry-on.js.map +1 -0
  264. package/dist/host/revocation.d.ts +16 -0
  265. package/dist/host/revocation.d.ts.map +1 -0
  266. package/dist/host/revocation.js +27 -0
  267. package/dist/host/revocation.js.map +1 -0
  268. package/dist/host/root.d.ts +37 -0
  269. package/dist/host/root.d.ts.map +1 -0
  270. package/dist/host/root.js +68 -0
  271. package/dist/host/root.js.map +1 -0
  272. package/dist/host/route.d.ts +64 -0
  273. package/dist/host/route.d.ts.map +1 -0
  274. package/dist/host/route.js +227 -0
  275. package/dist/host/route.js.map +1 -0
  276. package/dist/host/routines.d.ts +78 -0
  277. package/dist/host/routines.d.ts.map +1 -0
  278. package/dist/host/routines.js +398 -0
  279. package/dist/host/routines.js.map +1 -0
  280. package/dist/host/sleep.d.ts +9 -0
  281. package/dist/host/sleep.d.ts.map +1 -0
  282. package/dist/host/sleep.js +40 -0
  283. package/dist/host/sleep.js.map +1 -0
  284. package/dist/host/staging.d.ts +94 -0
  285. package/dist/host/staging.d.ts.map +1 -0
  286. package/dist/host/staging.js +304 -0
  287. package/dist/host/staging.js.map +1 -0
  288. package/dist/host/unbound-clock.d.ts +23 -0
  289. package/dist/host/unbound-clock.d.ts.map +1 -0
  290. package/dist/host/unbound-clock.js +58 -0
  291. package/dist/host/unbound-clock.js.map +1 -0
  292. package/dist/host/unbound.d.ts +37 -0
  293. package/dist/host/unbound.d.ts.map +1 -0
  294. package/dist/host/unbound.js +88 -0
  295. package/dist/host/unbound.js.map +1 -0
  296. package/dist/host/uuid.d.ts +3 -0
  297. package/dist/host/uuid.d.ts.map +1 -0
  298. package/dist/host/uuid.js +38 -0
  299. package/dist/host/uuid.js.map +1 -0
  300. package/dist/index.d.ts +29 -18
  301. package/dist/index.d.ts.map +1 -1
  302. package/dist/index.js +20 -9
  303. package/dist/index.js.map +1 -1
  304. package/dist/jobs/definition.d.ts +96 -0
  305. package/dist/jobs/definition.d.ts.map +1 -0
  306. package/dist/jobs/definition.js +83 -0
  307. package/dist/jobs/definition.js.map +1 -0
  308. package/dist/jobs/index.d.ts +5 -0
  309. package/dist/jobs/index.d.ts.map +1 -0
  310. package/dist/jobs/index.js +3 -0
  311. package/dist/jobs/index.js.map +1 -0
  312. package/dist/jobs/internal.d.ts +3 -0
  313. package/dist/jobs/internal.d.ts.map +1 -0
  314. package/dist/jobs/internal.js +4 -0
  315. package/dist/jobs/internal.js.map +1 -0
  316. package/dist/jobs/job.d.ts +149 -0
  317. package/dist/jobs/job.d.ts.map +1 -0
  318. package/dist/jobs/job.js +387 -0
  319. package/dist/jobs/job.js.map +1 -0
  320. package/dist/jobs/persisted.d.ts +38 -0
  321. package/dist/jobs/persisted.d.ts.map +1 -0
  322. package/dist/jobs/persisted.js +95 -0
  323. package/dist/jobs/persisted.js.map +1 -0
  324. package/dist/jobs/records.d.ts +231 -0
  325. package/dist/jobs/records.d.ts.map +1 -0
  326. package/dist/jobs/records.js +871 -0
  327. package/dist/jobs/records.js.map +1 -0
  328. package/dist/jobs/run-states.d.ts +69 -0
  329. package/dist/jobs/run-states.d.ts.map +1 -0
  330. package/dist/jobs/run-states.js +228 -0
  331. package/dist/jobs/run-states.js.map +1 -0
  332. package/dist/jobs/run.d.ts +117 -0
  333. package/dist/jobs/run.d.ts.map +1 -0
  334. package/dist/jobs/run.js +204 -0
  335. package/dist/jobs/run.js.map +1 -0
  336. package/dist/jobs/running.d.ts +44 -0
  337. package/dist/jobs/running.d.ts.map +1 -0
  338. package/dist/jobs/running.js +117 -0
  339. package/dist/jobs/running.js.map +1 -0
  340. package/dist/jobs/stored.d.ts +63 -0
  341. package/dist/jobs/stored.d.ts.map +1 -0
  342. package/dist/jobs/stored.js +55 -0
  343. package/dist/jobs/stored.js.map +1 -0
  344. package/dist/link/binary.d.ts +4 -0
  345. package/dist/link/binary.d.ts.map +1 -0
  346. package/dist/link/binary.js +544 -0
  347. package/dist/link/binary.js.map +1 -0
  348. package/dist/link/channel.d.ts +68 -0
  349. package/dist/link/channel.d.ts.map +1 -0
  350. package/dist/link/channel.js +215 -0
  351. package/dist/link/channel.js.map +1 -0
  352. package/dist/link/errors.d.ts +7 -0
  353. package/dist/link/errors.d.ts.map +1 -0
  354. package/dist/link/errors.js +21 -0
  355. package/dist/link/errors.js.map +1 -0
  356. package/dist/link/index.d.ts +8 -0
  357. package/dist/link/index.d.ts.map +1 -0
  358. package/dist/link/index.js +8 -0
  359. package/dist/link/index.js.map +1 -0
  360. package/dist/link/internal.d.ts +9 -0
  361. package/dist/link/internal.d.ts.map +1 -0
  362. package/dist/link/internal.js +10 -0
  363. package/dist/link/internal.js.map +1 -0
  364. package/dist/link/ipc.d.ts +22 -0
  365. package/dist/link/ipc.d.ts.map +1 -0
  366. package/dist/link/ipc.js +64 -0
  367. package/dist/link/ipc.js.map +1 -0
  368. package/dist/link/link.d.ts +34 -0
  369. package/dist/link/link.d.ts.map +1 -0
  370. package/dist/link/link.js +87 -0
  371. package/dist/link/link.js.map +1 -0
  372. package/dist/link/message.d.ts +262 -0
  373. package/dist/link/message.d.ts.map +1 -0
  374. package/dist/link/message.js +156 -0
  375. package/dist/link/message.js.map +1 -0
  376. package/dist/link/part.d.ts +80 -0
  377. package/dist/link/part.d.ts.map +1 -0
  378. package/dist/link/part.js +165 -0
  379. package/dist/link/part.js.map +1 -0
  380. package/dist/link/text.d.ts +6 -0
  381. package/dist/link/text.d.ts.map +1 -0
  382. package/dist/link/text.js +355 -0
  383. package/dist/link/text.js.map +1 -0
  384. package/dist/link/values.d.ts +40 -0
  385. package/dist/link/values.d.ts.map +1 -0
  386. package/dist/link/values.js +121 -0
  387. package/dist/link/values.js.map +1 -0
  388. package/dist/link/websocket.d.ts +26 -0
  389. package/dist/link/websocket.d.ts.map +1 -0
  390. package/dist/link/websocket.js +91 -0
  391. package/dist/link/websocket.js.map +1 -0
  392. package/dist/node/app/app.d.ts +269 -0
  393. package/dist/node/app/app.d.ts.map +1 -0
  394. package/dist/node/app/app.js +513 -0
  395. package/dist/node/app/app.js.map +1 -0
  396. package/dist/node/app/archive.d.ts +37 -0
  397. package/dist/node/app/archive.d.ts.map +1 -0
  398. package/dist/node/app/archive.js +204 -0
  399. package/dist/node/app/archive.js.map +1 -0
  400. package/dist/node/app/blobs.d.ts +23 -0
  401. package/dist/node/app/blobs.d.ts.map +1 -0
  402. package/dist/node/app/blobs.js +64 -0
  403. package/dist/node/app/blobs.js.map +1 -0
  404. package/dist/node/app/data.d.ts +35 -0
  405. package/dist/node/app/data.d.ts.map +1 -0
  406. package/dist/node/app/data.js +44 -0
  407. package/dist/node/app/data.js.map +1 -0
  408. package/dist/node/app/ephemeral-sessions.d.ts +20 -0
  409. package/dist/node/app/ephemeral-sessions.d.ts.map +1 -0
  410. package/dist/node/app/ephemeral-sessions.js +69 -0
  411. package/dist/node/app/ephemeral-sessions.js.map +1 -0
  412. package/dist/node/app/ephemeral.d.ts +11 -0
  413. package/dist/node/app/ephemeral.d.ts.map +1 -0
  414. package/dist/node/app/ephemeral.js +34 -0
  415. package/dist/node/app/ephemeral.js.map +1 -0
  416. package/dist/node/app/files-copy.d.ts +13 -0
  417. package/dist/node/app/files-copy.d.ts.map +1 -0
  418. package/dist/node/app/files-copy.js +86 -0
  419. package/dist/node/app/files-copy.js.map +1 -0
  420. package/dist/node/app/files-entry.d.ts +4 -0
  421. package/dist/node/app/files-entry.d.ts.map +1 -0
  422. package/dist/node/app/files-entry.js +7 -0
  423. package/dist/node/app/files-entry.js.map +1 -0
  424. package/dist/node/app/files-index.d.ts +180 -0
  425. package/dist/node/app/files-index.d.ts.map +1 -0
  426. package/dist/node/app/files-index.js +535 -0
  427. package/dist/node/app/files-index.js.map +1 -0
  428. package/dist/node/app/files.d.ts +363 -0
  429. package/dist/node/app/files.d.ts.map +1 -0
  430. package/dist/node/app/files.js +368 -0
  431. package/dist/node/app/files.js.map +1 -0
  432. package/dist/node/app/folder-views.d.ts +21 -0
  433. package/dist/node/app/folder-views.d.ts.map +1 -0
  434. package/dist/node/app/folder-views.js +55 -0
  435. package/dist/node/app/folder-views.js.map +1 -0
  436. package/dist/node/app/index.d.ts +12 -0
  437. package/dist/node/app/index.d.ts.map +1 -0
  438. package/dist/node/app/index.js +15 -0
  439. package/dist/node/app/index.js.map +1 -0
  440. package/dist/node/app/info.d.ts +66 -0
  441. package/dist/node/app/info.d.ts.map +1 -0
  442. package/dist/node/app/info.js +37 -0
  443. package/dist/node/app/info.js.map +1 -0
  444. package/dist/node/app/invite.d.ts +5 -0
  445. package/dist/node/app/invite.d.ts.map +1 -0
  446. package/dist/node/app/invite.js +64 -0
  447. package/dist/node/app/invite.js.map +1 -0
  448. package/dist/node/app/layout.d.ts +36 -0
  449. package/dist/node/app/layout.d.ts.map +1 -0
  450. package/dist/node/app/layout.js +87 -0
  451. package/dist/node/app/layout.js.map +1 -0
  452. package/dist/node/app/owner.d.ts +31 -0
  453. package/dist/node/app/owner.d.ts.map +1 -0
  454. package/dist/node/app/owner.js +104 -0
  455. package/dist/node/app/owner.js.map +1 -0
  456. package/dist/node/app/pairing.d.ts +55 -0
  457. package/dist/node/app/pairing.d.ts.map +1 -0
  458. package/dist/node/app/pairing.js +183 -0
  459. package/dist/node/app/pairing.js.map +1 -0
  460. package/dist/node/app/secrets.d.ts +16 -0
  461. package/dist/node/app/secrets.d.ts.map +1 -0
  462. package/dist/node/app/secrets.js +72 -0
  463. package/dist/node/app/secrets.js.map +1 -0
  464. package/dist/node/app/sessions.d.ts +72 -0
  465. package/dist/node/app/sessions.d.ts.map +1 -0
  466. package/dist/node/app/sessions.js +222 -0
  467. package/dist/node/app/sessions.js.map +1 -0
  468. package/dist/node/app/tar.d.ts +24 -0
  469. package/dist/node/app/tar.d.ts.map +1 -0
  470. package/dist/node/app/tar.js +167 -0
  471. package/dist/node/app/tar.js.map +1 -0
  472. package/dist/node/app/uploads.d.ts +37 -0
  473. package/dist/node/app/uploads.d.ts.map +1 -0
  474. package/dist/node/app/uploads.js +157 -0
  475. package/dist/node/app/uploads.js.map +1 -0
  476. package/dist/node/app/users.d.ts +37 -0
  477. package/dist/node/app/users.d.ts.map +1 -0
  478. package/dist/node/app/users.js +62 -0
  479. package/dist/node/app/users.js.map +1 -0
  480. package/dist/node/app/worker.d.ts +18 -0
  481. package/dist/node/app/worker.d.ts.map +1 -0
  482. package/dist/node/app/worker.js +84 -0
  483. package/dist/node/app/worker.js.map +1 -0
  484. package/dist/node/compression.d.ts +7 -0
  485. package/dist/node/compression.d.ts.map +1 -0
  486. package/dist/node/compression.js +25 -0
  487. package/dist/node/compression.js.map +1 -0
  488. package/dist/node/http/admission.d.ts +63 -0
  489. package/dist/node/http/admission.d.ts.map +1 -0
  490. package/dist/node/http/admission.js +134 -0
  491. package/dist/node/http/admission.js.map +1 -0
  492. package/dist/node/http/authenticate.d.ts +21 -0
  493. package/dist/node/http/authenticate.d.ts.map +1 -0
  494. package/dist/node/http/authenticate.js +34 -0
  495. package/dist/node/http/authenticate.js.map +1 -0
  496. package/dist/node/http/cookies.d.ts +32 -0
  497. package/dist/node/http/cookies.d.ts.map +1 -0
  498. package/dist/node/http/cookies.js +70 -0
  499. package/dist/node/http/cookies.js.map +1 -0
  500. package/dist/node/http/file.d.ts +23 -0
  501. package/dist/node/http/file.d.ts.map +1 -0
  502. package/dist/node/http/file.js +94 -0
  503. package/dist/node/http/file.js.map +1 -0
  504. package/dist/node/http/headers.d.ts +37 -0
  505. package/dist/node/http/headers.d.ts.map +1 -0
  506. package/dist/node/http/headers.js +136 -0
  507. package/dist/node/http/headers.js.map +1 -0
  508. package/dist/node/http/http.d.ts +111 -0
  509. package/dist/node/http/http.d.ts.map +1 -0
  510. package/dist/node/http/http.js +524 -0
  511. package/dist/node/http/http.js.map +1 -0
  512. package/dist/node/http/incoming.d.ts +19 -0
  513. package/dist/node/http/incoming.d.ts.map +1 -0
  514. package/dist/node/http/incoming.js +31 -0
  515. package/dist/node/http/incoming.js.map +1 -0
  516. package/dist/node/http/index.d.ts +11 -0
  517. package/dist/node/http/index.d.ts.map +1 -0
  518. package/dist/node/http/index.js +12 -0
  519. package/dist/node/http/index.js.map +1 -0
  520. package/dist/node/http/node.d.ts +78 -0
  521. package/dist/node/http/node.d.ts.map +1 -0
  522. package/dist/node/http/node.js +291 -0
  523. package/dist/node/http/node.js.map +1 -0
  524. package/dist/node/http/request.d.ts +60 -0
  525. package/dist/node/http/request.d.ts.map +1 -0
  526. package/dist/node/http/request.js +118 -0
  527. package/dist/node/http/request.js.map +1 -0
  528. package/dist/node/http/response.d.ts +63 -0
  529. package/dist/node/http/response.d.ts.map +1 -0
  530. package/dist/node/http/response.js +202 -0
  531. package/dist/node/http/response.js.map +1 -0
  532. package/dist/node/http/router.d.ts +132 -0
  533. package/dist/node/http/router.d.ts.map +1 -0
  534. package/dist/node/http/router.js +267 -0
  535. package/dist/node/http/router.js.map +1 -0
  536. package/dist/node/http/upgrades.d.ts +61 -0
  537. package/dist/node/http/upgrades.d.ts.map +1 -0
  538. package/dist/node/http/upgrades.js +192 -0
  539. package/dist/node/http/upgrades.js.map +1 -0
  540. package/dist/node/plugins/base-inputs.d.ts +14 -0
  541. package/dist/node/plugins/base-inputs.d.ts.map +1 -0
  542. package/dist/node/plugins/base-inputs.js +33 -0
  543. package/dist/node/plugins/base-inputs.js.map +1 -0
  544. package/dist/node/plugins/build.d.ts +77 -0
  545. package/dist/node/plugins/build.d.ts.map +1 -0
  546. package/dist/node/plugins/build.js +576 -0
  547. package/dist/node/plugins/build.js.map +1 -0
  548. package/dist/node/plugins/css-modules.d.ts +13 -0
  549. package/dist/node/plugins/css-modules.d.ts.map +1 -0
  550. package/dist/node/plugins/css-modules.js +58 -0
  551. package/dist/node/plugins/css-modules.js.map +1 -0
  552. package/dist/node/plugins/discover.d.ts +67 -0
  553. package/dist/node/plugins/discover.d.ts.map +1 -0
  554. package/dist/node/plugins/discover.js +369 -0
  555. package/dist/node/plugins/discover.js.map +1 -0
  556. package/dist/node/plugins/evaluate.d.ts +33 -0
  557. package/dist/node/plugins/evaluate.d.ts.map +1 -0
  558. package/dist/node/plugins/evaluate.js +121 -0
  559. package/dist/node/plugins/evaluate.js.map +1 -0
  560. package/dist/node/plugins/index.d.ts +11 -0
  561. package/dist/node/plugins/index.d.ts.map +1 -0
  562. package/dist/node/plugins/index.js +13 -0
  563. package/dist/node/plugins/index.js.map +1 -0
  564. package/dist/node/plugins/install.d.ts +38 -0
  565. package/dist/node/plugins/install.d.ts.map +1 -0
  566. package/dist/node/plugins/install.js +213 -0
  567. package/dist/node/plugins/install.js.map +1 -0
  568. package/dist/node/plugins/plugins.d.ts +162 -0
  569. package/dist/node/plugins/plugins.d.ts.map +1 -0
  570. package/dist/node/plugins/plugins.js +244 -0
  571. package/dist/node/plugins/plugins.js.map +1 -0
  572. package/dist/node/plugins/runtime.d.ts +57 -0
  573. package/dist/node/plugins/runtime.d.ts.map +1 -0
  574. package/dist/node/plugins/runtime.js +92 -0
  575. package/dist/node/plugins/runtime.js.map +1 -0
  576. package/dist/node/plugins/stack.d.ts +16 -0
  577. package/dist/node/plugins/stack.d.ts.map +1 -0
  578. package/dist/node/plugins/stack.js +61 -0
  579. package/dist/node/plugins/stack.js.map +1 -0
  580. package/dist/node/plugins/testing.d.ts +58 -0
  581. package/dist/node/plugins/testing.d.ts.map +1 -0
  582. package/dist/node/plugins/testing.js +210 -0
  583. package/dist/node/plugins/testing.js.map +1 -0
  584. package/dist/node/plugins/watcher.d.ts +69 -0
  585. package/dist/node/plugins/watcher.d.ts.map +1 -0
  586. package/dist/node/plugins/watcher.js +622 -0
  587. package/dist/node/plugins/watcher.js.map +1 -0
  588. package/dist/node/surfaces/bundle.d.ts +31 -0
  589. package/dist/node/surfaces/bundle.d.ts.map +1 -0
  590. package/dist/node/surfaces/bundle.js +118 -0
  591. package/dist/node/surfaces/bundle.js.map +1 -0
  592. package/dist/node/surfaces/current.d.ts +17 -0
  593. package/dist/node/surfaces/current.d.ts.map +1 -0
  594. package/dist/node/surfaces/current.js +54 -0
  595. package/dist/node/surfaces/current.js.map +1 -0
  596. package/dist/node/surfaces/index.d.ts +6 -0
  597. package/dist/node/surfaces/index.d.ts.map +1 -0
  598. package/dist/node/surfaces/index.js +6 -0
  599. package/dist/node/surfaces/index.js.map +1 -0
  600. package/dist/node/surfaces/published.d.ts +27 -0
  601. package/dist/node/surfaces/published.d.ts.map +1 -0
  602. package/dist/node/surfaces/published.js +142 -0
  603. package/dist/node/surfaces/published.js.map +1 -0
  604. package/dist/node/surfaces/served.d.ts +15 -0
  605. package/dist/node/surfaces/served.d.ts.map +1 -0
  606. package/dist/node/surfaces/served.js +42 -0
  607. package/dist/node/surfaces/served.js.map +1 -0
  608. package/dist/node/surfaces/surface-build.d.ts +53 -0
  609. package/dist/node/surfaces/surface-build.d.ts.map +1 -0
  610. package/dist/node/surfaces/surface-build.js +105 -0
  611. package/dist/node/surfaces/surface-build.js.map +1 -0
  612. package/dist/node/surfaces/tui.d.ts +40 -0
  613. package/dist/node/surfaces/tui.d.ts.map +1 -0
  614. package/dist/node/surfaces/tui.js +55 -0
  615. package/dist/node/surfaces/tui.js.map +1 -0
  616. package/dist/node/surfaces/web.d.ts +56 -0
  617. package/dist/node/surfaces/web.d.ts.map +1 -0
  618. package/dist/node/surfaces/web.js +108 -0
  619. package/dist/node/surfaces/web.js.map +1 -0
  620. package/dist/node/tui/actions.d.ts +49 -0
  621. package/dist/node/tui/actions.d.ts.map +1 -0
  622. package/dist/node/tui/actions.js +195 -0
  623. package/dist/node/tui/actions.js.map +1 -0
  624. package/dist/node/tui/credentials.d.ts +17 -0
  625. package/dist/node/tui/credentials.d.ts.map +1 -0
  626. package/dist/node/tui/credentials.js +54 -0
  627. package/dist/node/tui/credentials.js.map +1 -0
  628. package/dist/node/tui/filter.d.ts +5 -0
  629. package/dist/node/tui/filter.d.ts.map +1 -0
  630. package/dist/node/tui/filter.js +79 -0
  631. package/dist/node/tui/filter.js.map +1 -0
  632. package/dist/node/tui/index.d.ts +6 -0
  633. package/dist/node/tui/index.d.ts.map +1 -0
  634. package/dist/node/tui/index.js +6 -0
  635. package/dist/node/tui/index.js.map +1 -0
  636. package/dist/node/tui/launcher.d.ts +40 -0
  637. package/dist/node/tui/launcher.d.ts.map +1 -0
  638. package/dist/node/tui/launcher.js +439 -0
  639. package/dist/node/tui/launcher.js.map +1 -0
  640. package/dist/node/tui/pipe.d.ts +18 -0
  641. package/dist/node/tui/pipe.d.ts.map +1 -0
  642. package/dist/node/tui/pipe.js +134 -0
  643. package/dist/node/tui/pipe.js.map +1 -0
  644. package/dist/node/tui/sandbox.d.ts +54 -0
  645. package/dist/node/tui/sandbox.d.ts.map +1 -0
  646. package/dist/node/tui/sandbox.js +431 -0
  647. package/dist/node/tui/sandbox.js.map +1 -0
  648. package/dist/node/workers/base.d.ts +30 -0
  649. package/dist/node/workers/base.d.ts.map +1 -0
  650. package/dist/node/workers/base.js +255 -0
  651. package/dist/node/workers/base.js.map +1 -0
  652. package/dist/node/workers/child.d.ts +4 -0
  653. package/dist/node/workers/child.d.ts.map +1 -0
  654. package/dist/node/workers/child.js +6 -0
  655. package/dist/node/workers/child.js.map +1 -0
  656. package/dist/node/workers/control.d.ts +83 -0
  657. package/dist/node/workers/control.d.ts.map +1 -0
  658. package/dist/node/workers/control.js +77 -0
  659. package/dist/node/workers/control.js.map +1 -0
  660. package/dist/node/workers/index.d.ts +4 -0
  661. package/dist/node/workers/index.d.ts.map +1 -0
  662. package/dist/node/workers/index.js +7 -0
  663. package/dist/node/workers/index.js.map +1 -0
  664. package/dist/node/workers/lock.d.ts +30 -0
  665. package/dist/node/workers/lock.d.ts.map +1 -0
  666. package/dist/node/workers/lock.js +180 -0
  667. package/dist/node/workers/lock.js.map +1 -0
  668. package/dist/node/workers/main.d.ts +46 -0
  669. package/dist/node/workers/main.d.ts.map +1 -0
  670. package/dist/node/workers/main.js +230 -0
  671. package/dist/node/workers/main.js.map +1 -0
  672. package/dist/node/workers/process.d.ts +42 -0
  673. package/dist/node/workers/process.d.ts.map +1 -0
  674. package/dist/node/workers/process.js +125 -0
  675. package/dist/node/workers/process.js.map +1 -0
  676. package/dist/node/workers/workers.d.ts +122 -0
  677. package/dist/node/workers/workers.d.ts.map +1 -0
  678. package/dist/node/workers/workers.js +677 -0
  679. package/dist/node/workers/workers.js.map +1 -0
  680. package/dist/output.d.ts +1 -1
  681. package/dist/output.d.ts.map +1 -1
  682. package/dist/output.js +4 -2
  683. package/dist/output.js.map +1 -1
  684. package/dist/react/hooks.d.ts +43 -0
  685. package/dist/react/hooks.d.ts.map +1 -0
  686. package/dist/react/hooks.js +82 -0
  687. package/dist/react/hooks.js.map +1 -0
  688. package/dist/react/index.d.ts +3 -0
  689. package/dist/react/index.d.ts.map +1 -0
  690. package/dist/react/index.js +4 -0
  691. package/dist/react/index.js.map +1 -0
  692. package/dist/react/stores.d.ts +9 -0
  693. package/dist/react/stores.d.ts.map +1 -0
  694. package/dist/react/stores.js +37 -0
  695. package/dist/react/stores.js.map +1 -0
  696. package/dist/registries/contribution.d.ts +50 -0
  697. package/dist/registries/contribution.d.ts.map +1 -0
  698. package/dist/registries/contribution.js +129 -0
  699. package/dist/registries/contribution.js.map +1 -0
  700. package/dist/registries/entries.d.ts +18 -0
  701. package/dist/registries/entries.d.ts.map +1 -0
  702. package/dist/registries/entries.js +42 -0
  703. package/dist/registries/entries.js.map +1 -0
  704. package/dist/registries/index.d.ts +3 -0
  705. package/dist/registries/index.d.ts.map +1 -0
  706. package/dist/registries/index.js +5 -0
  707. package/dist/registries/index.js.map +1 -0
  708. package/dist/registries/internal.d.ts +4 -0
  709. package/dist/registries/internal.d.ts.map +1 -0
  710. package/dist/registries/internal.js +5 -0
  711. package/dist/registries/internal.js.map +1 -0
  712. package/dist/registries/record.d.ts +115 -0
  713. package/dist/registries/record.d.ts.map +1 -0
  714. package/dist/registries/record.js +283 -0
  715. package/dist/registries/record.js.map +1 -0
  716. package/dist/registries/registry.d.ts +74 -0
  717. package/dist/registries/registry.d.ts.map +1 -0
  718. package/dist/registries/registry.js +14 -0
  719. package/dist/registries/registry.js.map +1 -0
  720. package/dist/registries/value.d.ts +48 -0
  721. package/dist/registries/value.d.ts.map +1 -0
  722. package/dist/registries/value.js +224 -0
  723. package/dist/registries/value.js.map +1 -0
  724. package/dist/remote/calls.d.ts +25 -0
  725. package/dist/remote/calls.d.ts.map +1 -0
  726. package/dist/remote/calls.js +62 -0
  727. package/dist/remote/calls.js.map +1 -0
  728. package/dist/remote/consumer.d.ts +43 -0
  729. package/dist/remote/consumer.d.ts.map +1 -0
  730. package/dist/remote/consumer.js +350 -0
  731. package/dist/remote/consumer.js.map +1 -0
  732. package/dist/remote/hold.d.ts +141 -0
  733. package/dist/remote/hold.d.ts.map +1 -0
  734. package/dist/remote/hold.js +579 -0
  735. package/dist/remote/hold.js.map +1 -0
  736. package/dist/remote/host-link.d.ts +77 -0
  737. package/dist/remote/host-link.d.ts.map +1 -0
  738. package/dist/remote/host-link.js +184 -0
  739. package/dist/remote/host-link.js.map +1 -0
  740. package/dist/remote/internal.d.ts +6 -0
  741. package/dist/remote/internal.d.ts.map +1 -0
  742. package/dist/remote/internal.js +6 -0
  743. package/dist/remote/internal.js.map +1 -0
  744. package/dist/remote/path.d.ts +46 -0
  745. package/dist/remote/path.d.ts.map +1 -0
  746. package/dist/remote/path.js +73 -0
  747. package/dist/remote/path.js.map +1 -0
  748. package/dist/remote/provider.d.ts +89 -0
  749. package/dist/remote/provider.d.ts.map +1 -0
  750. package/dist/remote/provider.js +597 -0
  751. package/dist/remote/provider.js.map +1 -0
  752. package/dist/remote/relay.d.ts +69 -0
  753. package/dist/remote/relay.d.ts.map +1 -0
  754. package/dist/remote/relay.js +219 -0
  755. package/dist/remote/relay.js.map +1 -0
  756. package/dist/remote/remote-object.d.ts +138 -0
  757. package/dist/remote/remote-object.d.ts.map +1 -0
  758. package/dist/remote/remote-object.js +492 -0
  759. package/dist/remote/remote-object.js.map +1 -0
  760. package/dist/remote/replica.d.ts +59 -0
  761. package/dist/remote/replica.d.ts.map +1 -0
  762. package/dist/remote/replica.js +125 -0
  763. package/dist/remote/replica.js.map +1 -0
  764. package/dist/sqlite/cloudflare.d.ts +2 -0
  765. package/dist/sqlite/cloudflare.d.ts.map +1 -1
  766. package/dist/sqlite/cloudflare.js +10 -0
  767. package/dist/sqlite/cloudflare.js.map +1 -1
  768. package/dist/sqlite/database.d.ts +5 -2
  769. package/dist/sqlite/database.d.ts.map +1 -1
  770. package/dist/sqlite/database.js.map +1 -1
  771. package/dist/sqlite/node.d.ts +13 -2
  772. package/dist/sqlite/node.d.ts.map +1 -1
  773. package/dist/sqlite/node.js +31 -8
  774. package/dist/sqlite/node.js.map +1 -1
  775. package/dist/state/batch.d.ts +64 -0
  776. package/dist/state/batch.d.ts.map +1 -0
  777. package/dist/state/batch.js +164 -0
  778. package/dist/state/batch.js.map +1 -0
  779. package/dist/state/derive.d.ts +52 -0
  780. package/dist/state/derive.d.ts.map +1 -0
  781. package/dist/state/derive.js +182 -0
  782. package/dist/state/derive.js.map +1 -0
  783. package/dist/state/index.d.ts +6 -0
  784. package/dist/state/index.d.ts.map +1 -0
  785. package/dist/state/index.js +4 -0
  786. package/dist/state/index.js.map +1 -0
  787. package/dist/state/internal.d.ts +6 -0
  788. package/dist/state/internal.d.ts.map +1 -0
  789. package/dist/state/internal.js +8 -0
  790. package/dist/state/internal.js.map +1 -0
  791. package/dist/state/native-source.d.ts +106 -0
  792. package/dist/state/native-source.d.ts.map +1 -0
  793. package/dist/state/native-source.js +240 -0
  794. package/dist/state/native-source.js.map +1 -0
  795. package/dist/state/watchable.d.ts +114 -0
  796. package/dist/state/watchable.d.ts.map +1 -0
  797. package/dist/state/watchable.js +156 -0
  798. package/dist/state/watchable.js.map +1 -0
  799. package/dist/state/writable.d.ts +32 -0
  800. package/dist/state/writable.d.ts.map +1 -0
  801. package/dist/state/writable.js +49 -0
  802. package/dist/state/writable.js.map +1 -0
  803. package/dist/store/adapter.d.ts +67 -0
  804. package/dist/store/adapter.d.ts.map +1 -0
  805. package/dist/store/adapter.js +118 -0
  806. package/dist/store/adapter.js.map +1 -0
  807. package/dist/store/allocator.d.ts +17 -0
  808. package/dist/store/allocator.d.ts.map +1 -0
  809. package/dist/store/allocator.js +30 -0
  810. package/dist/store/allocator.js.map +1 -0
  811. package/dist/store/applier.d.ts +8 -0
  812. package/dist/store/applier.d.ts.map +1 -0
  813. package/dist/store/applier.js +375 -0
  814. package/dist/store/applier.js.map +1 -0
  815. package/dist/store/apply-batch.d.ts +12 -0
  816. package/dist/store/apply-batch.d.ts.map +1 -0
  817. package/dist/store/apply-batch.js +83 -0
  818. package/dist/store/apply-batch.js.map +1 -0
  819. package/dist/store/archive.d.ts +32 -0
  820. package/dist/store/archive.d.ts.map +1 -0
  821. package/dist/store/archive.js +130 -0
  822. package/dist/store/archive.js.map +1 -0
  823. package/dist/store/backend.d.ts +10 -0
  824. package/dist/store/backend.d.ts.map +1 -0
  825. package/dist/store/backend.js +15 -0
  826. package/dist/store/backend.js.map +1 -0
  827. package/dist/store/catalog.d.ts +24 -0
  828. package/dist/store/catalog.d.ts.map +1 -0
  829. package/dist/store/catalog.js +17 -0
  830. package/dist/store/catalog.js.map +1 -0
  831. package/dist/store/claims.d.ts +23 -0
  832. package/dist/store/claims.d.ts.map +1 -0
  833. package/dist/store/claims.js +65 -0
  834. package/dist/store/claims.js.map +1 -0
  835. package/dist/store/columns.d.ts +77 -0
  836. package/dist/store/columns.d.ts.map +1 -0
  837. package/dist/store/columns.js +77 -0
  838. package/dist/store/columns.js.map +1 -0
  839. package/dist/store/engine.d.ts +176 -0
  840. package/dist/store/engine.d.ts.map +1 -0
  841. package/dist/store/engine.js +283 -0
  842. package/dist/store/engine.js.map +1 -0
  843. package/dist/store/evaluate.d.ts +17 -0
  844. package/dist/store/evaluate.d.ts.map +1 -0
  845. package/dist/store/evaluate.js +128 -0
  846. package/dist/store/evaluate.js.map +1 -0
  847. package/dist/store/export.d.ts +17 -0
  848. package/dist/store/export.d.ts.map +1 -0
  849. package/dist/store/export.js +200 -0
  850. package/dist/store/export.js.map +1 -0
  851. package/dist/store/expression.d.ts +150 -0
  852. package/dist/store/expression.d.ts.map +1 -0
  853. package/dist/store/expression.js +268 -0
  854. package/dist/store/expression.js.map +1 -0
  855. package/dist/store/import.d.ts +10 -0
  856. package/dist/store/import.d.ts.map +1 -0
  857. package/dist/store/import.js +276 -0
  858. package/dist/store/import.js.map +1 -0
  859. package/dist/store/index.d.ts +16 -0
  860. package/dist/store/index.d.ts.map +1 -0
  861. package/dist/store/index.js +13 -0
  862. package/dist/store/index.js.map +1 -0
  863. package/dist/store/json-column.d.ts +33 -0
  864. package/dist/store/json-column.d.ts.map +1 -0
  865. package/dist/store/json-column.js +62 -0
  866. package/dist/store/json-column.js.map +1 -0
  867. package/dist/store/jsonl.d.ts +9 -0
  868. package/dist/store/jsonl.d.ts.map +1 -0
  869. package/dist/store/jsonl.js +61 -0
  870. package/dist/store/jsonl.js.map +1 -0
  871. package/dist/store/live-query.d.ts +108 -0
  872. package/dist/store/live-query.d.ts.map +1 -0
  873. package/dist/store/live-query.js +254 -0
  874. package/dist/store/live-query.js.map +1 -0
  875. package/dist/store/outbox.d.ts +26 -0
  876. package/dist/store/outbox.d.ts.map +1 -0
  877. package/dist/store/outbox.js +80 -0
  878. package/dist/store/outbox.js.map +1 -0
  879. package/dist/store/query.d.ts +39 -0
  880. package/dist/store/query.d.ts.map +1 -0
  881. package/dist/store/query.js +97 -0
  882. package/dist/store/query.js.map +1 -0
  883. package/dist/store/refusal.d.ts +15 -0
  884. package/dist/store/refusal.d.ts.map +1 -0
  885. package/dist/store/refusal.js +36 -0
  886. package/dist/store/refusal.js.map +1 -0
  887. package/dist/store/rows.d.ts +80 -0
  888. package/dist/store/rows.d.ts.map +1 -0
  889. package/dist/store/rows.js +183 -0
  890. package/dist/store/rows.js.map +1 -0
  891. package/dist/store/schema.d.ts +25 -0
  892. package/dist/store/schema.d.ts.map +1 -0
  893. package/dist/store/schema.js +115 -0
  894. package/dist/store/schema.js.map +1 -0
  895. package/dist/store/sql.d.ts +73 -0
  896. package/dist/store/sql.d.ts.map +1 -0
  897. package/dist/store/sql.js +234 -0
  898. package/dist/store/sql.js.map +1 -0
  899. package/dist/store/step.d.ts +50 -0
  900. package/dist/store/step.d.ts.map +1 -0
  901. package/dist/store/step.js +52 -0
  902. package/dist/store/step.js.map +1 -0
  903. package/dist/store/store.d.ts +171 -0
  904. package/dist/store/store.d.ts.map +1 -0
  905. package/dist/store/store.js +818 -0
  906. package/dist/store/store.js.map +1 -0
  907. package/dist/store/table-changes.d.ts +29 -0
  908. package/dist/store/table-changes.d.ts.map +1 -0
  909. package/dist/store/table-changes.js +102 -0
  910. package/dist/store/table-changes.js.map +1 -0
  911. package/dist/store/table-evolve.d.ts +74 -0
  912. package/dist/store/table-evolve.d.ts.map +1 -0
  913. package/dist/store/table-evolve.js +201 -0
  914. package/dist/store/table-evolve.js.map +1 -0
  915. package/dist/store/table-handle.d.ts +73 -0
  916. package/dist/store/table-handle.d.ts.map +1 -0
  917. package/dist/store/table-handle.js +101 -0
  918. package/dist/store/table-handle.js.map +1 -0
  919. package/dist/store/table-history.d.ts +75 -0
  920. package/dist/store/table-history.d.ts.map +1 -0
  921. package/dist/store/table-history.js +42 -0
  922. package/dist/store/table-history.js.map +1 -0
  923. package/dist/store/table-migration.d.ts +16 -0
  924. package/dist/store/table-migration.d.ts.map +1 -0
  925. package/dist/store/table-migration.js +202 -0
  926. package/dist/store/table-migration.js.map +1 -0
  927. package/dist/store/table-writes.d.ts +125 -0
  928. package/dist/store/table-writes.d.ts.map +1 -0
  929. package/dist/store/table-writes.js +170 -0
  930. package/dist/store/table-writes.js.map +1 -0
  931. package/dist/store/table.d.ts +80 -0
  932. package/dist/store/table.d.ts.map +1 -0
  933. package/dist/store/table.js +103 -0
  934. package/dist/store/table.js.map +1 -0
  935. package/dist/store/text.d.ts +14 -0
  936. package/dist/store/text.d.ts.map +1 -0
  937. package/dist/store/text.js +51 -0
  938. package/dist/store/text.js.map +1 -0
  939. package/dist/store/writes.d.ts +5 -0
  940. package/dist/store/writes.d.ts.map +1 -0
  941. package/dist/store/writes.js +4 -0
  942. package/dist/store/writes.js.map +1 -0
  943. package/dist/surfaces/active-language.d.ts +20 -0
  944. package/dist/surfaces/active-language.d.ts.map +1 -0
  945. package/dist/surfaces/active-language.js +78 -0
  946. package/dist/surfaces/active-language.js.map +1 -0
  947. package/dist/surfaces/active-theme.d.ts +16 -0
  948. package/dist/surfaces/active-theme.d.ts.map +1 -0
  949. package/dist/surfaces/active-theme.js +47 -0
  950. package/dist/surfaces/active-theme.js.map +1 -0
  951. package/dist/surfaces/client.d.ts +96 -0
  952. package/dist/surfaces/client.d.ts.map +1 -0
  953. package/dist/surfaces/client.js +264 -0
  954. package/dist/surfaces/client.js.map +1 -0
  955. package/dist/surfaces/connection.d.ts +49 -0
  956. package/dist/surfaces/connection.d.ts.map +1 -0
  957. package/dist/surfaces/connection.js +142 -0
  958. package/dist/surfaces/connection.js.map +1 -0
  959. package/dist/surfaces/format.d.ts +5 -0
  960. package/dist/surfaces/format.d.ts.map +1 -0
  961. package/dist/surfaces/format.js +37 -0
  962. package/dist/surfaces/format.js.map +1 -0
  963. package/dist/surfaces/index.d.ts +15 -0
  964. package/dist/surfaces/index.d.ts.map +1 -0
  965. package/dist/surfaces/index.js +18 -0
  966. package/dist/surfaces/index.js.map +1 -0
  967. package/dist/surfaces/language.d.ts +53 -0
  968. package/dist/surfaces/language.d.ts.map +1 -0
  969. package/dist/surfaces/language.js +74 -0
  970. package/dist/surfaces/language.js.map +1 -0
  971. package/dist/surfaces/loaded.d.ts +42 -0
  972. package/dist/surfaces/loaded.d.ts.map +1 -0
  973. package/dist/surfaces/loaded.js +116 -0
  974. package/dist/surfaces/loaded.js.map +1 -0
  975. package/dist/surfaces/locale-choice.d.ts +25 -0
  976. package/dist/surfaces/locale-choice.d.ts.map +1 -0
  977. package/dist/surfaces/locale-choice.js +14 -0
  978. package/dist/surfaces/locale-choice.js.map +1 -0
  979. package/dist/surfaces/messages.d.ts +67 -0
  980. package/dist/surfaces/messages.d.ts.map +1 -0
  981. package/dist/surfaces/messages.js +112 -0
  982. package/dist/surfaces/messages.js.map +1 -0
  983. package/dist/surfaces/page-state.d.ts +14 -0
  984. package/dist/surfaces/page-state.d.ts.map +1 -0
  985. package/dist/surfaces/page-state.js +43 -0
  986. package/dist/surfaces/page-state.js.map +1 -0
  987. package/dist/surfaces/preference.d.ts +32 -0
  988. package/dist/surfaces/preference.d.ts.map +1 -0
  989. package/dist/surfaces/preference.js +72 -0
  990. package/dist/surfaces/preference.js.map +1 -0
  991. package/dist/surfaces/registered.d.ts +33 -0
  992. package/dist/surfaces/registered.d.ts.map +1 -0
  993. package/dist/surfaces/registered.js +51 -0
  994. package/dist/surfaces/registered.js.map +1 -0
  995. package/dist/surfaces/scripts.d.ts +84 -0
  996. package/dist/surfaces/scripts.d.ts.map +1 -0
  997. package/dist/surfaces/scripts.js +28 -0
  998. package/dist/surfaces/scripts.js.map +1 -0
  999. package/dist/surfaces/theme-choice.d.ts +31 -0
  1000. package/dist/surfaces/theme-choice.d.ts.map +1 -0
  1001. package/dist/surfaces/theme-choice.js +18 -0
  1002. package/dist/surfaces/theme-choice.js.map +1 -0
  1003. package/dist/surfaces/themes.d.ts +43 -0
  1004. package/dist/surfaces/themes.d.ts.map +1 -0
  1005. package/dist/surfaces/themes.js +110 -0
  1006. package/dist/surfaces/themes.js.map +1 -0
  1007. package/dist/surfaces/translations.d.ts +29 -0
  1008. package/dist/surfaces/translations.d.ts.map +1 -0
  1009. package/dist/surfaces/translations.js +57 -0
  1010. package/dist/surfaces/translations.js.map +1 -0
  1011. package/dist/sync/batch.d.ts +18 -0
  1012. package/dist/sync/batch.d.ts.map +1 -0
  1013. package/dist/sync/batch.js +125 -0
  1014. package/dist/sync/batch.js.map +1 -0
  1015. package/dist/sync/client.d.ts +166 -0
  1016. package/dist/sync/client.d.ts.map +1 -0
  1017. package/dist/sync/client.js +438 -0
  1018. package/dist/sync/client.js.map +1 -0
  1019. package/dist/sync/files.d.ts +46 -0
  1020. package/dist/sync/files.d.ts.map +1 -0
  1021. package/dist/sync/files.js +13 -0
  1022. package/dist/sync/files.js.map +1 -0
  1023. package/dist/sync/filesystem.d.ts +37 -0
  1024. package/dist/sync/filesystem.d.ts.map +1 -0
  1025. package/dist/sync/filesystem.js +185 -0
  1026. package/dist/sync/filesystem.js.map +1 -0
  1027. package/dist/sync/index.d.ts +8 -0
  1028. package/dist/sync/index.d.ts.map +1 -0
  1029. package/dist/sync/index.js +9 -0
  1030. package/dist/sync/index.js.map +1 -0
  1031. package/dist/sync/lines.d.ts +18 -0
  1032. package/dist/sync/lines.d.ts.map +1 -0
  1033. package/dist/sync/lines.js +46 -0
  1034. package/dist/sync/lines.js.map +1 -0
  1035. package/dist/sync/remote.d.ts +130 -0
  1036. package/dist/sync/remote.d.ts.map +1 -0
  1037. package/dist/sync/remote.js +46 -0
  1038. package/dist/sync/remote.js.map +1 -0
  1039. package/dist/sync/state.d.ts +17 -0
  1040. package/dist/sync/state.d.ts.map +1 -0
  1041. package/dist/sync/state.js +40 -0
  1042. package/dist/sync/state.js.map +1 -0
  1043. package/dist/telemetry-ingest/batch.d.ts +70 -0
  1044. package/dist/telemetry-ingest/batch.d.ts.map +1 -0
  1045. package/dist/telemetry-ingest/batch.js +110 -0
  1046. package/dist/telemetry-ingest/batch.js.map +1 -0
  1047. package/dist/telemetry-ingest/facet.d.ts +21 -0
  1048. package/dist/telemetry-ingest/facet.d.ts.map +1 -0
  1049. package/dist/telemetry-ingest/facet.js +96 -0
  1050. package/dist/telemetry-ingest/facet.js.map +1 -0
  1051. package/dist/telemetry-ingest/index.d.ts +5 -0
  1052. package/dist/telemetry-ingest/index.d.ts.map +1 -0
  1053. package/dist/telemetry-ingest/index.js +8 -0
  1054. package/dist/telemetry-ingest/index.js.map +1 -0
  1055. package/dist/telemetry-ingest/recorder.d.ts +50 -0
  1056. package/dist/telemetry-ingest/recorder.d.ts.map +1 -0
  1057. package/dist/telemetry-ingest/recorder.js +298 -0
  1058. package/dist/telemetry-ingest/recorder.js.map +1 -0
  1059. package/dist/telemetry-ingest/sender.d.ts +14 -0
  1060. package/dist/telemetry-ingest/sender.d.ts.map +1 -0
  1061. package/dist/telemetry-ingest/sender.js +64 -0
  1062. package/dist/telemetry-ingest/sender.js.map +1 -0
  1063. package/dist/telemetry-sqlite/index.d.ts +13 -4
  1064. package/dist/telemetry-sqlite/index.d.ts.map +1 -1
  1065. package/dist/telemetry-sqlite/index.js +81 -241
  1066. package/dist/telemetry-sqlite/index.js.map +1 -1
  1067. package/dist/telemetry-sqlite/node.d.ts +13 -0
  1068. package/dist/telemetry-sqlite/node.d.ts.map +1 -0
  1069. package/dist/telemetry-sqlite/node.js +27 -0
  1070. package/dist/telemetry-sqlite/node.js.map +1 -0
  1071. package/dist/telemetry-sqlite/schema.d.ts +9 -0
  1072. package/dist/telemetry-sqlite/schema.d.ts.map +1 -0
  1073. package/dist/telemetry-sqlite/schema.js +61 -0
  1074. package/dist/telemetry-sqlite/schema.js.map +1 -0
  1075. package/dist/telemetry-sqlite/store.d.ts +3 -0
  1076. package/dist/telemetry-sqlite/store.d.ts.map +1 -1
  1077. package/dist/telemetry-sqlite/store.js +24 -13
  1078. package/dist/telemetry-sqlite/store.js.map +1 -1
  1079. package/dist/telemetry.d.ts +937 -0
  1080. package/dist/telemetry.d.ts.map +1 -0
  1081. package/dist/telemetry.js +470 -0
  1082. package/dist/telemetry.js.map +1 -0
  1083. package/dist/tui/bridge.d.ts +112 -0
  1084. package/dist/tui/bridge.d.ts.map +1 -0
  1085. package/dist/tui/bridge.js +9 -0
  1086. package/dist/tui/bridge.js.map +1 -0
  1087. package/dist/tui/channel.d.ts +44 -0
  1088. package/dist/tui/channel.d.ts.map +1 -0
  1089. package/dist/tui/channel.js +150 -0
  1090. package/dist/tui/channel.js.map +1 -0
  1091. package/dist/tui/frames.d.ts +5 -0
  1092. package/dist/tui/frames.d.ts.map +1 -0
  1093. package/dist/tui/frames.js +52 -0
  1094. package/dist/tui/frames.js.map +1 -0
  1095. package/dist/tui/index.d.ts +7 -0
  1096. package/dist/tui/index.d.ts.map +1 -0
  1097. package/dist/tui/index.js +8 -0
  1098. package/dist/tui/index.js.map +1 -0
  1099. package/dist/tui/runtime.d.ts +46 -0
  1100. package/dist/tui/runtime.d.ts.map +1 -0
  1101. package/dist/tui/runtime.js +101 -0
  1102. package/dist/tui/runtime.js.map +1 -0
  1103. package/dist/tui/scope.d.ts +46 -0
  1104. package/dist/tui/scope.d.ts.map +1 -0
  1105. package/dist/tui/scope.js +141 -0
  1106. package/dist/tui/scope.js.map +1 -0
  1107. package/dist/tui/terminal.d.ts +15 -0
  1108. package/dist/tui/terminal.d.ts.map +1 -0
  1109. package/dist/tui/terminal.js +37 -0
  1110. package/dist/tui/terminal.js.map +1 -0
  1111. package/dist/tui/theme.d.ts +17 -0
  1112. package/dist/tui/theme.d.ts.map +1 -0
  1113. package/dist/tui/theme.js +38 -0
  1114. package/dist/tui/theme.js.map +1 -0
  1115. package/dist/watch.d.ts +194 -0
  1116. package/dist/watch.d.ts.map +1 -0
  1117. package/dist/watch.js +383 -0
  1118. package/dist/watch.js.map +1 -0
  1119. package/dist/web/environment.d.ts +4 -0
  1120. package/dist/web/environment.d.ts.map +1 -0
  1121. package/dist/web/environment.js +37 -0
  1122. package/dist/web/environment.js.map +1 -0
  1123. package/dist/web/index.d.ts +5 -0
  1124. package/dist/web/index.d.ts.map +1 -0
  1125. package/dist/web/index.js +7 -0
  1126. package/dist/web/index.js.map +1 -0
  1127. package/dist/web/language.d.ts +7 -0
  1128. package/dist/web/language.d.ts.map +1 -0
  1129. package/dist/web/language.js +21 -0
  1130. package/dist/web/language.js.map +1 -0
  1131. package/dist/web/page.d.ts +29 -0
  1132. package/dist/web/page.d.ts.map +1 -0
  1133. package/dist/web/page.js +92 -0
  1134. package/dist/web/page.js.map +1 -0
  1135. package/dist/web/scripts.d.ts +23 -0
  1136. package/dist/web/scripts.d.ts.map +1 -0
  1137. package/dist/web/scripts.js +50 -0
  1138. package/dist/web/scripts.js.map +1 -0
  1139. package/dist/web/styles.d.ts +17 -0
  1140. package/dist/web/styles.d.ts.map +1 -0
  1141. package/dist/web/styles.js +218 -0
  1142. package/dist/web/styles.js.map +1 -0
  1143. package/dist/web/themes.d.ts +6 -0
  1144. package/dist/web/themes.d.ts.map +1 -0
  1145. package/dist/web/themes.js +31 -0
  1146. package/dist/web/themes.js.map +1 -0
  1147. package/docs/benchmarks.md +1036 -0
  1148. package/docs/decisions.md +3436 -0
  1149. package/docs/dependencies/book.md +1671 -0
  1150. package/docs/dependencies/index.html +2641 -0
  1151. package/docs/dependencies/model.md +330 -0
  1152. package/docs/design.md +3065 -0
  1153. package/docs/durable-observers/book.md +432 -0
  1154. package/docs/durable-observers/index.html +517 -0
  1155. package/docs/flow-control/book.md +333 -0
  1156. package/docs/flow-control/fold/index.html +265 -0
  1157. package/docs/flow-control/index.html +548 -0
  1158. package/docs/flow-control/window/index.html +228 -0
  1159. package/docs/guide-plugins-hosts/book.md +957 -0
  1160. package/docs/guide-plugins-hosts/index.html +952 -0
  1161. package/docs/http-workers/book.md +378 -0
  1162. package/docs/http-workers/index.html +515 -0
  1163. package/docs/i18n/book.md +217 -0
  1164. package/docs/i18n/index.html +344 -0
  1165. package/docs/layer-1.md +311 -0
  1166. package/docs/layer-2.md +216 -0
  1167. package/docs/p3-features/README.md +6 -0
  1168. package/docs/p3-features/book.md +478 -0
  1169. package/docs/plugin-authoring.md +276 -0
  1170. package/docs/plugin-model/book.md +186 -0
  1171. package/docs/plugin-model/index.html +310 -0
  1172. package/docs/plugin-primer/book.md +273 -0
  1173. package/docs/plugin-primer/index.html +430 -0
  1174. package/docs/slice-1.md +236 -0
  1175. package/docs/slice-10.md +288 -0
  1176. package/docs/slice-11.md +114 -0
  1177. package/docs/slice-12.md +132 -0
  1178. package/docs/slice-13.md +121 -0
  1179. package/docs/slice-2.md +174 -0
  1180. package/docs/slice-3a.md +296 -0
  1181. package/docs/slice-3b.md +197 -0
  1182. package/docs/slice-4.md +146 -0
  1183. package/docs/slice-4a.md +418 -0
  1184. package/docs/slice-4b.md +208 -0
  1185. package/docs/slice-5.md +281 -0
  1186. package/docs/slice-6a.md +676 -0
  1187. package/docs/slice-6b.md +332 -0
  1188. package/docs/slice-7a.md +130 -0
  1189. package/docs/slice-7b/book.md +608 -0
  1190. package/docs/slice-7b/index.html +842 -0
  1191. package/docs/slice-7b.md +255 -0
  1192. package/docs/slice-7c.md +165 -0
  1193. package/docs/slice-8.md +194 -0
  1194. package/docs/slice-9.md +110 -0
  1195. package/docs/slices.md +241 -0
  1196. package/docs/store/book.md +670 -0
  1197. package/docs/store/index.html +861 -0
  1198. package/docs/store/walkthrough.md +193 -0
  1199. package/docs/theming/book.md +223 -0
  1200. package/docs/theming/index.html +371 -0
  1201. package/docs/tutorial/book.md +2169 -0
  1202. package/docs/tutorial/index.html +2112 -0
  1203. package/docs/tutorial/screens/click-after.png +0 -0
  1204. package/docs/tutorial/screens/click-before.png +0 -0
  1205. package/docs/tutorial/screens/edited.png +0 -0
  1206. package/docs/tutorial/screens/french.png +0 -0
  1207. package/docs/tutorial/screens/harbor.png +0 -0
  1208. package/docs/tutorial/screens/page.png +0 -0
  1209. package/docs/tutorial/screens/traces-ada.png +0 -0
  1210. package/docs/tutorial/screens/traces.png +0 -0
  1211. package/package.json +114 -20
  1212. package/src/delta/README.md +69 -0
  1213. package/dist/cell.d.ts +0 -122
  1214. package/dist/cell.d.ts.map +0 -1
  1215. package/dist/cell.js +0 -356
  1216. package/dist/cell.js.map +0 -1
  1217. package/dist/cluster.d.ts +0 -27
  1218. package/dist/cluster.d.ts.map +0 -1
  1219. package/dist/cluster.js +0 -230
  1220. package/dist/cluster.js.map +0 -1
  1221. package/dist/connection.d.ts +0 -270
  1222. package/dist/connection.d.ts.map +0 -1
  1223. package/dist/connection.js +0 -1216
  1224. package/dist/connection.js.map +0 -1
  1225. package/dist/contract.d.ts +0 -208
  1226. package/dist/contract.d.ts.map +0 -1
  1227. package/dist/contract.js +0 -246
  1228. package/dist/contract.js.map +0 -1
  1229. package/dist/declare.d.ts +0 -33
  1230. package/dist/declare.d.ts.map +0 -1
  1231. package/dist/declare.js +0 -2
  1232. package/dist/declare.js.map +0 -1
  1233. package/dist/errors.d.ts +0 -28
  1234. package/dist/errors.d.ts.map +0 -1
  1235. package/dist/errors.js +0 -59
  1236. package/dist/errors.js.map +0 -1
  1237. package/dist/host.d.ts +0 -348
  1238. package/dist/host.d.ts.map +0 -1
  1239. package/dist/host.js +0 -1000
  1240. package/dist/host.js.map +0 -1
  1241. package/dist/link.d.ts +0 -107
  1242. package/dist/link.d.ts.map +0 -1
  1243. package/dist/link.js +0 -355
  1244. package/dist/link.js.map +0 -1
  1245. package/dist/loader.d.ts +0 -4
  1246. package/dist/loader.d.ts.map +0 -1
  1247. package/dist/loader.js +0 -73
  1248. package/dist/loader.js.map +0 -1
  1249. package/dist/manager.d.ts +0 -115
  1250. package/dist/manager.d.ts.map +0 -1
  1251. package/dist/manager.js +0 -345
  1252. package/dist/manager.js.map +0 -1
  1253. package/dist/node.d.ts +0 -4
  1254. package/dist/node.d.ts.map +0 -1
  1255. package/dist/node.js +0 -4
  1256. package/dist/node.js.map +0 -1
  1257. package/dist/object.d.ts +0 -438
  1258. package/dist/object.d.ts.map +0 -1
  1259. package/dist/object.js +0 -1571
  1260. package/dist/object.js.map +0 -1
  1261. package/dist/publish.d.ts +0 -5
  1262. package/dist/publish.d.ts.map +0 -1
  1263. package/dist/publish.js +0 -40
  1264. package/dist/publish.js.map +0 -1
  1265. package/dist/registry.d.ts +0 -25
  1266. package/dist/registry.d.ts.map +0 -1
  1267. package/dist/registry.js +0 -6
  1268. package/dist/registry.js.map +0 -1
  1269. package/dist/reload.d.ts +0 -126
  1270. package/dist/reload.d.ts.map +0 -1
  1271. package/dist/reload.js +0 -653
  1272. package/dist/reload.js.map +0 -1
  1273. package/dist/remote.d.ts +0 -165
  1274. package/dist/remote.d.ts.map +0 -1
  1275. package/dist/remote.js +0 -612
  1276. package/dist/remote.js.map +0 -1
  1277. package/dist/schema.d.ts +0 -21
  1278. package/dist/schema.d.ts.map +0 -1
  1279. package/dist/schema.js +0 -228
  1280. package/dist/schema.js.map +0 -1
  1281. package/dist/state.d.ts +0 -92
  1282. package/dist/state.d.ts.map +0 -1
  1283. package/dist/state.js +0 -287
  1284. package/dist/state.js.map +0 -1
  1285. package/dist/types.d.ts +0 -88
  1286. package/dist/types.d.ts.map +0 -1
  1287. package/dist/types.js +0 -2
  1288. package/dist/types.js.map +0 -1
  1289. package/dist/websocket.d.ts +0 -15
  1290. package/dist/websocket.d.ts.map +0 -1
  1291. package/dist/websocket.js +0 -16
  1292. package/dist/websocket.js.map +0 -1
  1293. package/dist/wire.d.ts +0 -216
  1294. package/dist/wire.d.ts.map +0 -1
  1295. package/dist/wire.js +0 -165
  1296. package/dist/wire.js.map +0 -1
  1297. package/docs/guide.md +0 -814
  1298. package/docs/spec.md +0 -288
  1299. package/docs/tutorial.md +0 -931
@@ -0,0 +1,183 @@
1
+ // Device pairing (slice 13 §2, decision "The app kit, point 3" (c)): a command-line or terminal client on another
2
+ // machine asks for a code (`POST /_chord/pair`, public) and polls with a secret it got with it; the owner (the
3
+ // principal the app names) opens `/_chord/pair/<code>` in a signed-in browser and approves; the next poll returns a
4
+ // token of the owner's new device session, once. Codes are short, random, single use and expire after 10 minutes; the
5
+ // poll secret is kept only hashed. Asking is public, so pairings anonymous clients start are capped: `maxPending` in
6
+ // all (100 by default) and `perAddress` per client address (10). The trade: a party filling the caps locks pairing out
7
+ // for others for up to 10 minutes (behind a tunnel every remote client has the tunnel's address), instead of growing
8
+ // the server's memory without bound; a signed-in owner's pairings are not counted, so the owner can always pair.
9
+ import { randomInt } from "node:crypto";
10
+ import { samePrincipal } from "../../data/principal.js";
11
+ import { defineFacet } from "../../host/index.js";
12
+ import { Http } from "../http/index.js";
13
+ import { hashToken, newToken } from "./secrets.js";
14
+ import { Sessions } from "./sessions.js";
15
+ /** How long a pairing code is valid: 10 minutes. */
16
+ const PAIRING_MS = 10 * 60_000;
17
+ /** The code's letters: no 0/O, 1/I/L. */
18
+ const ALPHABET = "ABCDEFGHJKMNPQRSTUVWXYZ23456789";
19
+ /** The pairings under way, by code and by their poll secret's hash, with the anonymous ones counted. */
20
+ export class Pairings {
21
+ #byCode = new Map();
22
+ #byPoll = new Map();
23
+ #perAddress = new Map();
24
+ #anonymous = 0;
25
+ #maxPending;
26
+ #maxPerAddress;
27
+ constructor(limits = {}) {
28
+ this.#maxPending = limits.maxPending ?? 100;
29
+ this.#maxPerAddress = limits.perAddress ?? 10;
30
+ }
31
+ /**
32
+ * A new pairing for a device labelled `label`, started `by` the owner or an anonymous client: its code (for the
33
+ * owner) and its poll secret (for the device); `undefined` when an anonymous client reached a limit.
34
+ */
35
+ begin(label, by) {
36
+ this.#expire();
37
+ if (by.kind === "anonymous") {
38
+ const full = this.#anonymous >= this.#maxPending;
39
+ if (full || (this.#perAddress.get(by.address) ?? 0) >= this.#maxPerAddress)
40
+ return undefined;
41
+ this.#anonymous++;
42
+ this.#perAddress.set(by.address, (this.#perAddress.get(by.address) ?? 0) + 1);
43
+ }
44
+ let code;
45
+ do
46
+ code = `${letters(4)}-${letters(4)}`;
47
+ while (this.#byCode.has(code));
48
+ const poll = newToken();
49
+ const pairing = { code, label, by, expires: Date.now() + PAIRING_MS };
50
+ this.#byCode.set(code, pairing);
51
+ this.#byPoll.set(hashToken(poll), pairing);
52
+ return { code, poll };
53
+ }
54
+ /** The pairing waiting for approval under `code` (any case), unexpired. */
55
+ waiting(code) {
56
+ this.#expire();
57
+ const pairing = this.#byCode.get(code.toUpperCase());
58
+ return pairing?.token === undefined ? pairing : undefined;
59
+ }
60
+ /** What a poll with `poll` learns: still waiting, the device's token (once: the pairing ends), or nothing. */
61
+ poll(poll) {
62
+ this.#expire();
63
+ const hash = hashToken(poll);
64
+ const pairing = this.#byPoll.get(hash);
65
+ if (pairing === undefined)
66
+ return undefined;
67
+ if (pairing.token === undefined)
68
+ return { kind: "waiting" };
69
+ this.#end(hash, pairing);
70
+ return { kind: "approved", token: pairing.token };
71
+ }
72
+ /** Drops the expired pairings. */
73
+ #expire() {
74
+ const now = Date.now();
75
+ for (const [hash, pairing] of this.#byPoll) {
76
+ if (pairing.expires <= now)
77
+ this.#end(hash, pairing);
78
+ }
79
+ }
80
+ /** Ends `pairing` (its poll secret's hash `hash`). */
81
+ #end(hash, pairing) {
82
+ this.#byPoll.delete(hash);
83
+ this.#byCode.delete(pairing.code);
84
+ const { by } = pairing;
85
+ if (by.kind === "owner")
86
+ return;
87
+ this.#anonymous--;
88
+ const left = (this.#perAddress.get(by.address) ?? 1) - 1;
89
+ if (left === 0)
90
+ this.#perAddress.delete(by.address);
91
+ else
92
+ this.#perAddress.set(by.address, left);
93
+ }
94
+ }
95
+ /** `count` random letters of `ALPHABET` (`crypto.randomInt`). */
96
+ function letters(count) {
97
+ let text = "";
98
+ for (let index = 0; index < count; index++)
99
+ text += ALPHABET[randomInt(ALPHABET.length)];
100
+ return text;
101
+ }
102
+ /** The pairing routes' prefix. */
103
+ export const PAIR_PATH = "/_chord/pair";
104
+ /**
105
+ * The kit's facet for device pairing: `POST /_chord/pair` (public: `{ label? }` → `{ code, poll }`, 429 past a limit
106
+ * unless the owner asks), `POST /_chord/pair/poll` (public: `{ poll }` → `{ status: "waiting" }`, `{ status:
107
+ * "approved", token }` once, else 404), `GET` and `POST /_chord/pair/:code` (`owner`'s confirm page and approval: a
108
+ * device session of `owner`).
109
+ */
110
+ export function pairingFacet(pairings, owner) {
111
+ return defineFacet((_host, self) => self.contribute(Http, {
112
+ routes: {
113
+ [`POST ${PAIR_PATH}`]: {
114
+ public: true,
115
+ handler: async (request, ctx) => {
116
+ const label = await labelOf(request);
117
+ const by = samePrincipal(ctx.principal, owner, ctx)
118
+ ? { kind: "owner" }
119
+ : { kind: "anonymous", address: request.remoteAddress ?? "" };
120
+ const begun = pairings.begin(label, by);
121
+ return begun === undefined ? { kind: "error", status: 429 } : { kind: "json", value: begun };
122
+ },
123
+ },
124
+ [`POST ${PAIR_PATH}/poll`]: {
125
+ public: true,
126
+ handler: async (request) => {
127
+ // A trust boundary: anyone may poll.
128
+ const body = (await request.json());
129
+ const polled = typeof body?.poll === "string" ? pairings.poll(body.poll) : undefined;
130
+ if (polled === undefined)
131
+ return { kind: "error", status: 404 };
132
+ if (polled.kind === "waiting")
133
+ return { kind: "json", value: { status: "waiting" } };
134
+ return { kind: "json", value: { status: "approved", token: polled.token } };
135
+ },
136
+ },
137
+ [`GET ${PAIR_PATH}/:code`]: async (request, ctx) => {
138
+ if (!samePrincipal(ctx.principal, owner, ctx))
139
+ return { kind: "error", status: 403 };
140
+ const pairing = pairings.waiting(request.params.code ?? "");
141
+ if (pairing === undefined)
142
+ return { kind: "html", status: 404, body: "<p>No such pairing (or it expired).</p>" };
143
+ return { kind: "html", body: confirmPage(pairing.code, pairing.label) };
144
+ },
145
+ [`POST ${PAIR_PATH}/:code`]: async (request, ctx) => {
146
+ if (!samePrincipal(ctx.principal, owner, ctx))
147
+ return { kind: "error", status: 403 };
148
+ const pairing = pairings.waiting(request.params.code ?? "");
149
+ if (pairing === undefined)
150
+ return { kind: "html", status: 404, body: "<p>No such pairing (or it expired).</p>" };
151
+ const sessions = await ctx.get(Sessions, {});
152
+ const { token } = await sessions.issue({ principal: owner, label: pairing.label, kind: "device" }, ctx);
153
+ pairing.token = token;
154
+ return {
155
+ kind: "html",
156
+ body: `<p>Approved: ${escapeHtml(pairing.label)} is signed in as the owner.</p>`,
157
+ };
158
+ },
159
+ },
160
+ }));
161
+ }
162
+ /** The device's label from a pairing request's body (`{ label }`, at most 100 characters), else `device`. */
163
+ async function labelOf(request) {
164
+ const declared = Number(request.headers.get("content-length") ?? "0");
165
+ if (declared === 0 && request.headers.get("transfer-encoding") === null)
166
+ return "device";
167
+ // A trust boundary: anyone may ask for a code.
168
+ const body = (await request.json(4096));
169
+ return typeof body?.label === "string" && body.label.trim() !== "" ? body.label.trim().slice(0, 100) : "device";
170
+ }
171
+ /** The owner's confirm page for pairing `code` (a form posting to itself: same origin, the session cookie). */
172
+ function confirmPage(code, label) {
173
+ return [
174
+ "<!doctype html><title>Pair a device</title>",
175
+ `<p>Sign in <b>${escapeHtml(label)}</b> as the owner? Its code: <b>${escapeHtml(code)}</b> (compare it with the device).</p>`,
176
+ '<form method="post"><button>Approve</button></form>',
177
+ ].join("\n");
178
+ }
179
+ /** `text` safe in HTML. */
180
+ function escapeHtml(text) {
181
+ return text.replace(/[&<>"']/g, (char) => `&#${char.charCodeAt(0)};`);
182
+ }
183
+ //# sourceMappingURL=pairing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairing.js","sourceRoot":"","sources":["../../../src/node/app/pairing.ts"],"names":[],"mappings":"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","sourcesContent":["// Device pairing (slice 13 §2, decision \"The app kit, point 3\" (c)): a command-line or terminal client on another\n// machine asks for a code (`POST /_chord/pair`, public) and polls with a secret it got with it; the owner (the\n// principal the app names) opens `/_chord/pair/<code>` in a signed-in browser and approves; the next poll returns a\n// token of the owner's new device session, once. Codes are short, random, single use and expire after 10 minutes; the\n// poll secret is kept only hashed. Asking is public, so pairings anonymous clients start are capped: `maxPending` in\n// all (100 by default) and `perAddress` per client address (10). The trade: a party filling the caps locks pairing out\n// for others for up to 10 minutes (behind a tunnel every remote client has the tunnel's address), instead of growing\n// the server's memory without bound; a signed-in owner's pairings are not counted, so the owner can always pair.\n\nimport { randomInt } from \"node:crypto\";\nimport type { Principal } from \"../../data/index.ts\";\nimport { samePrincipal } from \"../../data/principal.ts\";\nimport { defineFacet, type Facet } from \"../../host/index.ts\";\nimport { Http, type HttpRequest, type HttpResponse } from \"../http/index.ts\";\nimport { hashToken, newToken } from \"./secrets.ts\";\nimport { Sessions } from \"./sessions.ts\";\n\n/** How long a pairing code is valid: 10 minutes. */\nconst PAIRING_MS = 10 * 60_000;\n\n/** The code's letters: no 0/O, 1/I/L. */\nconst ALPHABET = \"ABCDEFGHJKMNPQRSTUVWXYZ23456789\";\n\n/** Who starts a pairing: the signed-in owner (not counted), or an anonymous client at an address (counted). */\nexport type PairingStarter = { readonly kind: \"owner\" } | { readonly kind: \"anonymous\"; readonly address: string };\n\n/** One pairing under way: its code, the device's label, who started it, its expiry, its token once approved. */\ntype Pairing = {\n\treadonly code: string;\n\treadonly label: string;\n\treadonly by: PairingStarter;\n\treadonly expires: number;\n\ttoken?: string;\n};\n\n/** The limits of pairings under way: in all (100 by default) and per client address (10 by default). */\nexport type PairingLimits = { readonly maxPending?: number; readonly perAddress?: number };\n\n/** The pairings under way, by code and by their poll secret's hash, with the anonymous ones counted. */\nexport class Pairings {\n\treadonly #byCode = new Map<string, Pairing>();\n\treadonly #byPoll = new Map<string, Pairing>();\n\treadonly #perAddress = new Map<string, number>();\n\t#anonymous = 0;\n\treadonly #maxPending: number;\n\treadonly #maxPerAddress: number;\n\n\tconstructor(limits: PairingLimits = {}) {\n\t\tthis.#maxPending = limits.maxPending ?? 100;\n\t\tthis.#maxPerAddress = limits.perAddress ?? 10;\n\t}\n\n\t/**\n\t * A new pairing for a device labelled `label`, started `by` the owner or an anonymous client: its code (for the\n\t * owner) and its poll secret (for the device); `undefined` when an anonymous client reached a limit.\n\t */\n\tbegin(label: string, by: PairingStarter): { readonly code: string; readonly poll: string } | undefined {\n\t\tthis.#expire();\n\t\tif (by.kind === \"anonymous\") {\n\t\t\tconst full = this.#anonymous >= this.#maxPending;\n\t\t\tif (full || (this.#perAddress.get(by.address) ?? 0) >= this.#maxPerAddress) return undefined;\n\t\t\tthis.#anonymous++;\n\t\t\tthis.#perAddress.set(by.address, (this.#perAddress.get(by.address) ?? 0) + 1);\n\t\t}\n\t\tlet code: string;\n\t\tdo code = `${letters(4)}-${letters(4)}`;\n\t\twhile (this.#byCode.has(code));\n\t\tconst poll = newToken();\n\t\tconst pairing: Pairing = { code, label, by, expires: Date.now() + PAIRING_MS };\n\t\tthis.#byCode.set(code, pairing);\n\t\tthis.#byPoll.set(hashToken(poll), pairing);\n\t\treturn { code, poll };\n\t}\n\n\t/** The pairing waiting for approval under `code` (any case), unexpired. */\n\twaiting(code: string): Pairing | undefined {\n\t\tthis.#expire();\n\t\tconst pairing = this.#byCode.get(code.toUpperCase());\n\t\treturn pairing?.token === undefined ? pairing : undefined;\n\t}\n\n\t/** What a poll with `poll` learns: still waiting, the device's token (once: the pairing ends), or nothing. */\n\tpoll(\n\t\tpoll: string,\n\t): { readonly kind: \"waiting\" } | { readonly kind: \"approved\"; readonly token: string } | undefined {\n\t\tthis.#expire();\n\t\tconst hash = hashToken(poll);\n\t\tconst pairing = this.#byPoll.get(hash);\n\t\tif (pairing === undefined) return undefined;\n\t\tif (pairing.token === undefined) return { kind: \"waiting\" };\n\t\tthis.#end(hash, pairing);\n\t\treturn { kind: \"approved\", token: pairing.token };\n\t}\n\n\t/** Drops the expired pairings. */\n\t#expire(): void {\n\t\tconst now = Date.now();\n\t\tfor (const [hash, pairing] of this.#byPoll) {\n\t\t\tif (pairing.expires <= now) this.#end(hash, pairing);\n\t\t}\n\t}\n\n\t/** Ends `pairing` (its poll secret's hash `hash`). */\n\t#end(hash: string, pairing: Pairing): void {\n\t\tthis.#byPoll.delete(hash);\n\t\tthis.#byCode.delete(pairing.code);\n\t\tconst { by } = pairing;\n\t\tif (by.kind === \"owner\") return;\n\t\tthis.#anonymous--;\n\t\tconst left = (this.#perAddress.get(by.address) ?? 1) - 1;\n\t\tif (left === 0) this.#perAddress.delete(by.address);\n\t\telse this.#perAddress.set(by.address, left);\n\t}\n}\n\n/** `count` random letters of `ALPHABET` (`crypto.randomInt`). */\nfunction letters(count: number): string {\n\tlet text = \"\";\n\tfor (let index = 0; index < count; index++) text += ALPHABET[randomInt(ALPHABET.length)];\n\treturn text;\n}\n\n/** The pairing routes' prefix. */\nexport const PAIR_PATH = \"/_chord/pair\";\n\n/**\n * The kit's facet for device pairing: `POST /_chord/pair` (public: `{ label? }` → `{ code, poll }`, 429 past a limit\n * unless the owner asks), `POST /_chord/pair/poll` (public: `{ poll }` → `{ status: \"waiting\" }`, `{ status:\n * \"approved\", token }` once, else 404), `GET` and `POST /_chord/pair/:code` (`owner`'s confirm page and approval: a\n * device session of `owner`).\n */\nexport function pairingFacet<P extends Principal>(pairings: Pairings, owner: P): Facet<P> {\n\treturn defineFacet<P>((_host, self) =>\n\t\tself.contribute(Http, {\n\t\t\troutes: {\n\t\t\t\t[`POST ${PAIR_PATH}`]: {\n\t\t\t\t\tpublic: true,\n\t\t\t\t\thandler: async (request, ctx): Promise<HttpResponse> => {\n\t\t\t\t\t\tconst label = await labelOf(request);\n\t\t\t\t\t\tconst by: PairingStarter = samePrincipal(ctx.principal, owner, ctx)\n\t\t\t\t\t\t\t? { kind: \"owner\" }\n\t\t\t\t\t\t\t: { kind: \"anonymous\", address: request.remoteAddress ?? \"\" };\n\t\t\t\t\t\tconst begun = pairings.begin(label, by);\n\t\t\t\t\t\treturn begun === undefined ? { kind: \"error\", status: 429 } : { kind: \"json\", value: begun };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t[`POST ${PAIR_PATH}/poll`]: {\n\t\t\t\t\tpublic: true,\n\t\t\t\t\thandler: async (request): Promise<HttpResponse> => {\n\t\t\t\t\t\t// A trust boundary: anyone may poll.\n\t\t\t\t\t\tconst body = (await request.json()) as { readonly poll?: unknown } | null;\n\t\t\t\t\t\tconst polled = typeof body?.poll === \"string\" ? pairings.poll(body.poll) : undefined;\n\t\t\t\t\t\tif (polled === undefined) return { kind: \"error\", status: 404 };\n\t\t\t\t\t\tif (polled.kind === \"waiting\") return { kind: \"json\", value: { status: \"waiting\" } };\n\t\t\t\t\t\treturn { kind: \"json\", value: { status: \"approved\", token: polled.token } };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t[`GET ${PAIR_PATH}/:code`]: async (request, ctx) => {\n\t\t\t\t\tif (!samePrincipal(ctx.principal, owner, ctx)) return { kind: \"error\", status: 403 };\n\t\t\t\t\tconst pairing = pairings.waiting(request.params.code ?? \"\");\n\t\t\t\t\tif (pairing === undefined)\n\t\t\t\t\t\treturn { kind: \"html\", status: 404, body: \"<p>No such pairing (or it expired).</p>\" };\n\t\t\t\t\treturn { kind: \"html\", body: confirmPage(pairing.code, pairing.label) };\n\t\t\t\t},\n\t\t\t\t[`POST ${PAIR_PATH}/:code`]: async (request, ctx) => {\n\t\t\t\t\tif (!samePrincipal(ctx.principal, owner, ctx)) return { kind: \"error\", status: 403 };\n\t\t\t\t\tconst pairing = pairings.waiting(request.params.code ?? \"\");\n\t\t\t\t\tif (pairing === undefined)\n\t\t\t\t\t\treturn { kind: \"html\", status: 404, body: \"<p>No such pairing (or it expired).</p>\" };\n\t\t\t\t\tconst sessions = await ctx.get(Sessions, {});\n\t\t\t\t\tconst { token } = await sessions.issue({ principal: owner, label: pairing.label, kind: \"device\" }, ctx);\n\t\t\t\t\tpairing.token = token;\n\t\t\t\t\treturn {\n\t\t\t\t\t\tkind: \"html\",\n\t\t\t\t\t\tbody: `<p>Approved: ${escapeHtml(pairing.label)} is signed in as the owner.</p>`,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t);\n}\n\n/** The device's label from a pairing request's body (`{ label }`, at most 100 characters), else `device`. */\nasync function labelOf(request: HttpRequest): Promise<string> {\n\tconst declared = Number(request.headers.get(\"content-length\") ?? \"0\");\n\tif (declared === 0 && request.headers.get(\"transfer-encoding\") === null) return \"device\";\n\t// A trust boundary: anyone may ask for a code.\n\tconst body = (await request.json(4096)) as { readonly label?: unknown } | null;\n\treturn typeof body?.label === \"string\" && body.label.trim() !== \"\" ? body.label.trim().slice(0, 100) : \"device\";\n}\n\n/** The owner's confirm page for pairing `code` (a form posting to itself: same origin, the session cookie). */\nfunction confirmPage(code: string, label: string): string {\n\treturn [\n\t\t\"<!doctype html><title>Pair a device</title>\",\n\t\t`<p>Sign in <b>${escapeHtml(label)}</b> as the owner? Its code: <b>${escapeHtml(code)}</b> (compare it with the device).</p>`,\n\t\t'<form method=\"post\"><button>Approve</button></form>',\n\t].join(\"\\n\");\n}\n\n/** `text` safe in HTML. */\nfunction escapeHtml(text: string): string {\n\treturn text.replace(/[&<>\"']/g, (char) => `&#${char.charCodeAt(0)};`);\n}\n"]}
@@ -0,0 +1,16 @@
1
+ /** A fresh random token of `bytes` bytes, base64url. */
2
+ export declare function newToken(bytes?: number): string;
3
+ /** The hash a token is kept as (SHA-256, hex): what leaks from a store is no credential. */
4
+ export declare function hashToken(token: string): string;
5
+ /** Whether `token` hashes to `hash`, compared in constant time. */
6
+ export declare function matchesHash(token: string, hash: string): boolean;
7
+ /** The secret in the file at `path`, created (mode 0600, in one step) with a fresh token when it does not exist yet. */
8
+ export declare function secretFile(path: string): Promise<string>;
9
+ /** The text of the secret file at `path`, or `undefined` when it does not exist. */
10
+ export declare function readSecret(path: string): Promise<string | undefined>;
11
+ /**
12
+ * Writes `text` to `path` with mode 0600 in one step: a temporary file of the same directory (made exclusively, 0600)
13
+ * linked into place (`create`: refused when `path` exists, `"exists"` returned) or renamed over it (`replace`).
14
+ */
15
+ export declare function writeSecret(path: string, text: string, mode: "create" | "replace"): Promise<"written" | "exists">;
16
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../../src/node/app/secrets.ts"],"names":[],"mappings":"AAQA,wDAAwD;AACxD,wBAAgB,QAAQ,CAAC,KAAK,SAAK,GAAG,MAAM,CAE3C;AAED,4FAA4F;AAC5F,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAIhE;AAED,wHAAwH;AACxH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAM9D;AAED,oFAAoF;AACpF,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAO1E;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAChC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,QAAQ,GAAG,SAAS,GACxB,OAAO,CAAC,SAAS,GAAG,QAAQ,CAAC,CAsB/B"}
@@ -0,0 +1,72 @@
1
+ // Secrets of the app kit (slice 13 §2): tokens from `crypto.randomBytes`, kept only as their SHA-256 hashes and
2
+ // compared in constant time, and secret files (the cookie key, the owner token file) created with mode 0600 in one
3
+ // step, so no other OS user and no half-written file ever reads them.
4
+ import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
5
+ import { link, open, readFile, rename, unlink } from "node:fs/promises";
6
+ import { dirname, join } from "node:path";
7
+ /** A fresh random token of `bytes` bytes, base64url. */
8
+ export function newToken(bytes = 32) {
9
+ return randomBytes(bytes).toString("base64url");
10
+ }
11
+ /** The hash a token is kept as (SHA-256, hex): what leaks from a store is no credential. */
12
+ export function hashToken(token) {
13
+ return createHash("sha256").update(token).digest("hex");
14
+ }
15
+ /** Whether `token` hashes to `hash`, compared in constant time. */
16
+ export function matchesHash(token, hash) {
17
+ const given = Buffer.from(hashToken(token), "hex");
18
+ const kept = Buffer.from(hash, "hex");
19
+ return given.length === kept.length && timingSafeEqual(given, kept);
20
+ }
21
+ /** The secret in the file at `path`, created (mode 0600, in one step) with a fresh token when it does not exist yet. */
22
+ export async function secretFile(path) {
23
+ const existing = await readSecret(path);
24
+ if (existing !== undefined)
25
+ return existing;
26
+ const secret = newToken();
27
+ const written = await writeSecret(path, secret, "create");
28
+ return written === "exists" ? ((await readSecret(path)) ?? secret) : secret;
29
+ }
30
+ /** The text of the secret file at `path`, or `undefined` when it does not exist. */
31
+ export async function readSecret(path) {
32
+ try {
33
+ return (await readFile(path, "utf8")).trim();
34
+ }
35
+ catch (error) {
36
+ if (error.code === "ENOENT")
37
+ return undefined;
38
+ throw error;
39
+ }
40
+ }
41
+ /**
42
+ * Writes `text` to `path` with mode 0600 in one step: a temporary file of the same directory (made exclusively, 0600)
43
+ * linked into place (`create`: refused when `path` exists, `"exists"` returned) or renamed over it (`replace`).
44
+ */
45
+ export async function writeSecret(path, text, mode) {
46
+ const temporary = join(dirname(path), `.${newToken(9)}.tmp`);
47
+ const handle = await open(temporary, "wx", 0o600);
48
+ try {
49
+ await handle.writeFile(`${text}\n`);
50
+ await handle.sync();
51
+ }
52
+ finally {
53
+ await handle.close();
54
+ }
55
+ try {
56
+ if (mode === "replace") {
57
+ await rename(temporary, path);
58
+ return "written";
59
+ }
60
+ await link(temporary, path);
61
+ return "written";
62
+ }
63
+ catch (error) {
64
+ if (error.code === "EEXIST")
65
+ return "exists";
66
+ throw error;
67
+ }
68
+ finally {
69
+ await unlink(temporary).catch(() => { });
70
+ }
71
+ }
72
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../src/node/app/secrets.ts"],"names":[],"mappings":"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","sourcesContent":["// Secrets of the app kit (slice 13 §2): tokens from `crypto.randomBytes`, kept only as their SHA-256 hashes and\n// compared in constant time, and secret files (the cookie key, the owner token file) created with mode 0600 in one\n// step, so no other OS user and no half-written file ever reads them.\n\nimport { createHash, randomBytes, timingSafeEqual } from \"node:crypto\";\nimport { link, open, readFile, rename, unlink } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\n/** A fresh random token of `bytes` bytes, base64url. */\nexport function newToken(bytes = 32): string {\n\treturn randomBytes(bytes).toString(\"base64url\");\n}\n\n/** The hash a token is kept as (SHA-256, hex): what leaks from a store is no credential. */\nexport function hashToken(token: string): string {\n\treturn createHash(\"sha256\").update(token).digest(\"hex\");\n}\n\n/** Whether `token` hashes to `hash`, compared in constant time. */\nexport function matchesHash(token: string, hash: string): boolean {\n\tconst given = Buffer.from(hashToken(token), \"hex\");\n\tconst kept = Buffer.from(hash, \"hex\");\n\treturn given.length === kept.length && timingSafeEqual(given, kept);\n}\n\n/** The secret in the file at `path`, created (mode 0600, in one step) with a fresh token when it does not exist yet. */\nexport async function secretFile(path: string): Promise<string> {\n\tconst existing = await readSecret(path);\n\tif (existing !== undefined) return existing;\n\tconst secret = newToken();\n\tconst written = await writeSecret(path, secret, \"create\");\n\treturn written === \"exists\" ? ((await readSecret(path)) ?? secret) : secret;\n}\n\n/** The text of the secret file at `path`, or `undefined` when it does not exist. */\nexport async function readSecret(path: string): Promise<string | undefined> {\n\ttry {\n\t\treturn (await readFile(path, \"utf8\")).trim();\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n\t\tthrow error;\n\t}\n}\n\n/**\n * Writes `text` to `path` with mode 0600 in one step: a temporary file of the same directory (made exclusively, 0600)\n * linked into place (`create`: refused when `path` exists, `\"exists\"` returned) or renamed over it (`replace`).\n */\nexport async function writeSecret(\n\tpath: string,\n\ttext: string,\n\tmode: \"create\" | \"replace\",\n): Promise<\"written\" | \"exists\"> {\n\tconst temporary = join(dirname(path), `.${newToken(9)}.tmp`);\n\tconst handle = await open(temporary, \"wx\", 0o600);\n\ttry {\n\t\tawait handle.writeFile(`${text}\\n`);\n\t\tawait handle.sync();\n\t} finally {\n\t\tawait handle.close();\n\t}\n\ttry {\n\t\tif (mode === \"replace\") {\n\t\t\tawait rename(temporary, path);\n\t\t\treturn \"written\";\n\t\t}\n\t\tawait link(temporary, path);\n\t\treturn \"written\";\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"EEXIST\") return \"exists\";\n\t\tthrow error;\n\t} finally {\n\t\tawait unlink(temporary).catch(() => {});\n\t}\n}\n"]}
@@ -0,0 +1,72 @@
1
+ import type { Principal } from "../../data/index.ts";
2
+ import { type Facet } from "../../host/index.ts";
3
+ import { type HttpRequest } from "../http/index.ts";
4
+ /** What a session is for: a browser (its cookie), a device (a command-line client's token), an ephemeral login. */
5
+ export type SessionKind = "browser" | "device" | "ephemeral";
6
+ /** A browser or device session as `Sessions.list` shows it: never its token or hash. */
7
+ export type SessionInfo = {
8
+ readonly id: string;
9
+ readonly label: string;
10
+ readonly kind: "browser" | "device";
11
+ readonly principal: unknown;
12
+ readonly created: number;
13
+ readonly lastUsed: number;
14
+ };
15
+ /** The kit's sessions (one per server): issue, verify, revoke, and the watchable list of persisted ones. */
16
+ export declare const Sessions: import("../../contracts/contract.ts").Contract<{
17
+ kind: "local";
18
+ name: "chord.app.sessions";
19
+ params: {};
20
+ history: [{
21
+ version: "1";
22
+ variants: {
23
+ members: {
24
+ state: {
25
+ readonly list: import("../../contracts/index.ts").Schema<{
26
+ id: string;
27
+ label: string;
28
+ kind: "browser" | "device";
29
+ principal: unknown;
30
+ created: number;
31
+ lastUsed: number;
32
+ }[]>;
33
+ };
34
+ methods: {
35
+ readonly issue: import("../../contracts/schema.ts").Method<import("../../contracts/index.ts").Schema<{
36
+ principal: unknown;
37
+ label: string;
38
+ kind: "browser" | "device" | "ephemeral";
39
+ secure?: boolean | undefined;
40
+ }>, import("../../contracts/index.ts").Schema<{
41
+ id: string;
42
+ token: string;
43
+ cookie: string;
44
+ }>>;
45
+ readonly verify: import("../../contracts/schema.ts").Method<import("../../contracts/schema.ts").StringSchema, import("../../contracts/index.ts").Schema<unknown>>;
46
+ readonly revoke: import("../../contracts/schema.ts").Method<import("../../contracts/schema.ts").StringSchema, import("../../contracts/schema.ts").NullSchema>;
47
+ };
48
+ keyed: {};
49
+ };
50
+ };
51
+ changes: never;
52
+ }];
53
+ }>;
54
+ /** The name of the kit's session cookie. */
55
+ export declare const SESSION_COOKIE = "chord-session";
56
+ /** The sessions' limits: how many ephemeral sessions live at once (1,000 by default; past it the oldest ends). */
57
+ export type SessionLimits = {
58
+ readonly maxEphemeral?: number;
59
+ };
60
+ /** The kit's sessions: the facet for the server's core facets, and the links endpoint's `opened` hook. */
61
+ export type KitSessions<P extends Principal> = {
62
+ readonly facet: Facet<P>;
63
+ /** A link opened with `request`'s credentials: an ephemeral session's links are counted (it ends with its last). */
64
+ readonly opened: (request: HttpRequest) => (() => void) | undefined;
65
+ };
66
+ /**
67
+ * The kit's sessions: its facet serving `Sessions` (a host-lifetime object) and contributing its authenticator (the
68
+ * bearer token first, else the session cookie signed with `cookieSecret`), and the links hook ending an ephemeral
69
+ * session with its client's connection.
70
+ */
71
+ export declare function createSessions<P extends Principal>(cookieSecret: string, limits?: SessionLimits): KitSessions<P>;
72
+ //# sourceMappingURL=sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/node/app/sessions.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAIN,KAAK,WAAW,EAKhB,MAAM,kBAAkB,CAAC;AAI1B,mHAAmH;AACnH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE7D,wFAAwF;AACxF,MAAM,MAAM,WAAW,GAAG;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,4GAA4G;AAC5G,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCnB,CAAC;AAEH,4CAA4C;AAC5C,eAAO,MAAM,cAAc,kBAAkB,CAAC;AA4B9C,kHAAkH;AAClH,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,0GAA0G;AAC1G,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,SAAS,IAAI;IAC9C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,oHAAoH;IACpH,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CACpE,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAE,aAAkB,GAAG,WAAW,CAAC,CAAC,CAAC,CAQpH"}
@@ -0,0 +1,222 @@
1
+ // Sessions (slice 13 §2, decision "The app kit, point 3: authentication"): the kit's object on the server that issues
2
+ // and revokes sessions, and its authenticator. A session is a principal behind a token `<id>.<secret>` (random); only
3
+ // the secret's hash is kept. A browser carries its token in the kit's signed session cookie (`HttpOnly`,
4
+ // `SameSite=Strict`), a command-line client in `Authorization: Bearer <token>`. Browser and device sessions persist in
5
+ // the server's store and expire after 400 days unused; ephemeral sessions (a pick-a-name login, a public route) live
6
+ // in memory only (`EphemeralSessions`), at most `maxEphemeral` of them (past it the oldest ends), so a public login
7
+ // costs the same whatever came before; each ends with its client's connection (its last link closed, a grace period
8
+ // passed: the links endpoint's `opened` hook counts them), and none outlives the server's run.
9
+ import { arr, bool, local, map, method, num, obj, oneOf, opt, str, unknown } from "../../contracts/index.js";
10
+ import { defineState } from "../../documents/index.js";
11
+ import { defineFacet } from "../../host/index.js";
12
+ import { Authenticators, cookie, Http, readCookie, readSignedCookie, } from "../http/index.js";
13
+ import { EphemeralSessions } from "./ephemeral-sessions.js";
14
+ import { hashToken, matchesHash, newToken } from "./secrets.js";
15
+ /** The kit's sessions (one per server): issue, verify, revoke, and the watchable list of persisted ones. */
16
+ export const Sessions = local("chord.app.sessions", {
17
+ version: 1,
18
+ params: {},
19
+ members: {
20
+ /** The browser and device sessions (ephemeral ones are not listed: there may be many, and they are short). */
21
+ list: arr(obj({
22
+ id: str(),
23
+ label: str(),
24
+ kind: oneOf("browser", "device"),
25
+ principal: unknown(),
26
+ created: num(),
27
+ lastUsed: num(),
28
+ })),
29
+ /**
30
+ * A new session for `principal`: its id, its token (shown once, kept only hashed) and the session cookie carrying
31
+ * it for a browser (`Set-Cookie`; `secure` for a remote one).
32
+ */
33
+ issue: method(obj({
34
+ principal: unknown(),
35
+ label: str(),
36
+ kind: oneOf("browser", "device", "ephemeral"),
37
+ secure: opt(bool()),
38
+ }), obj({ id: str(), token: str(), cookie: str() })),
39
+ /** The principal `token` authenticates as, or `null` (unknown, revoked, expired, malformed). */
40
+ verify: method(str(), unknown()),
41
+ /** Ends session `id` at once: its token authenticates nothing more. */
42
+ revoke: method(str()),
43
+ },
44
+ });
45
+ /** The name of the kit's session cookie. */
46
+ export const SESSION_COOKIE = "chord-session";
47
+ /** The stored sessions: by id, each with its secret's hash and its principal (as JSON text: any of the app's). */
48
+ const SessionsDocument = defineState("chord.app.sessions", {
49
+ schema: obj({
50
+ sessions: map(obj({
51
+ hash: str(),
52
+ label: str(),
53
+ kind: oneOf("browser", "device"),
54
+ principal: str(),
55
+ created: num(),
56
+ lastUsed: num(),
57
+ })),
58
+ }),
59
+ version: 1,
60
+ initial: () => ({ sessions: {} }),
61
+ persist: true,
62
+ checkpointWhen: (_value, _ops, { deltasSinceBase }) => deltasSinceBase >= 50,
63
+ });
64
+ /** How often a session's `lastUsed` is written at most: once a minute (not one commit per request). */
65
+ const TOUCH_MS = 60_000;
66
+ /** How long a persisted session lives unused: 400 days, as its cookie. */
67
+ const SESSION_IDLE_MS = 400 * 24 * 60 * 60_000;
68
+ /**
69
+ * The kit's sessions: its facet serving `Sessions` (a host-lifetime object) and contributing its authenticator (the
70
+ * bearer token first, else the session cookie signed with `cookieSecret`), and the links hook ending an ephemeral
71
+ * session with its client's connection.
72
+ */
73
+ export function createSessions(cookieSecret, limits = {}) {
74
+ const ephemeral = new EphemeralSessions(limits.maxEphemeral ?? 1000);
75
+ const opened = (request) => {
76
+ const token = bearerToken(request) ?? readCookie(request, SESSION_COOKIE, cookieSecret);
77
+ const dot = token?.indexOf(".") ?? -1;
78
+ return dot > 0 ? ephemeral.linkOpened(token.slice(0, dot)) : undefined;
79
+ };
80
+ return { facet: sessionsFacet(cookieSecret, ephemeral), opened };
81
+ }
82
+ /** The facet of `createSessions`. */
83
+ function sessionsFacet(cookieSecret, ephemeral) {
84
+ return defineFacet((host) => host.serve(Sessions, (_params, self) => {
85
+ const document = self.state(SessionsDocument);
86
+ const change = (fn, context) =>
87
+ // Not awaited by authentication: the request goes on; a write that fails is made again by a later request.
88
+ void document.change((draft) => fn(draft.sessions), context).catch(() => { });
89
+ /** The principal of `token`, or `undefined`; touches or lazily removes the persisted session it names. */
90
+ const authenticate = (token, context) => {
91
+ const dot = token.indexOf(".");
92
+ if (dot <= 0)
93
+ return undefined;
94
+ const id = token.slice(0, dot);
95
+ const secret = token.slice(dot + 1);
96
+ const short = ephemeral.get(id);
97
+ if (short !== undefined)
98
+ return matchesHash(secret, short.hash) ? short.principal : undefined;
99
+ // A trust boundary: `id` is the client's (`Object.hasOwn`: no inherited member is a session).
100
+ const sessions = document.value.sessions;
101
+ if (!Object.hasOwn(sessions, id))
102
+ return undefined;
103
+ const session = sessions[id];
104
+ if (!matchesHash(secret, session.hash))
105
+ return undefined;
106
+ const now = Date.now();
107
+ if (now - session.lastUsed > SESSION_IDLE_MS) {
108
+ change((draft) => {
109
+ delete draft[id];
110
+ }, context);
111
+ return undefined;
112
+ }
113
+ if (now - session.lastUsed > TOUCH_MS) {
114
+ change((draft) => {
115
+ if (Object.hasOwn(draft, id))
116
+ draft[id].lastUsed = now;
117
+ }, context);
118
+ }
119
+ // Stored by `issue` from a principal of the app's type.
120
+ return JSON.parse(session.principal);
121
+ };
122
+ self.contribute(Authenticators, (request, context) => {
123
+ const token = bearerToken(request) ?? readCookie(request, SESSION_COOKIE, cookieSecret);
124
+ return token === undefined ? undefined : authenticate(token, context);
125
+ });
126
+ self.contribute(Http, { wraps: [rollingCookie(cookieSecret, authenticate)] });
127
+ return {
128
+ list: self.derive([document], ([value]) => Object.entries(value.sessions).map(([id, { label, kind, principal, created, lastUsed }]) => ({
129
+ id,
130
+ label,
131
+ kind,
132
+ // Stored by `issue` as JSON text.
133
+ principal: JSON.parse(principal),
134
+ created,
135
+ lastUsed,
136
+ }))),
137
+ issue: async ({ principal, label, kind, secure }, ctx) => {
138
+ const id = newToken(12);
139
+ const secret = newToken(32);
140
+ if (kind === "ephemeral") {
141
+ // Principals are the app's: `issue`'s callers pass one of its type.
142
+ ephemeral.issue(id, hashToken(secret), principal);
143
+ }
144
+ else {
145
+ const now = Date.now();
146
+ const stored = JSON.stringify(principal);
147
+ await document.change((draft) => {
148
+ draft.sessions[id] = {
149
+ hash: hashToken(secret),
150
+ label,
151
+ kind,
152
+ principal: stored,
153
+ created: now,
154
+ lastUsed: now,
155
+ };
156
+ }, ctx);
157
+ }
158
+ const token = `${id}.${secret}`;
159
+ // Only whether the browser is remote matters to the cookie (`Secure`).
160
+ const provenance = secure === true ? { kind: "remote", host: "" } : { kind: "local" };
161
+ const set = sessionCookie(token, kind, { provenance }, cookieSecret);
162
+ return { id, token, cookie: set };
163
+ },
164
+ verify: async (token, ctx) => authenticate(token, ctx) ?? null,
165
+ revoke: async (id, ctx) => {
166
+ if (ephemeral.revoke(id))
167
+ return null;
168
+ await document.change((draft) => {
169
+ delete draft.sessions[id];
170
+ }, ctx);
171
+ return null;
172
+ },
173
+ };
174
+ }));
175
+ }
176
+ /**
177
+ * The session cookie carrying `token` (a session of `kind`) for a browser of `request`'s provenance: a persisted
178
+ * session's lives as long as the session does unused (400 days, renewed by `rollingCookie`), an ephemeral one's only
179
+ * while the browser runs.
180
+ */
181
+ function sessionCookie(token, kind, request, secret) {
182
+ const maxAge = kind === "ephemeral" ? undefined : SESSION_IDLE_MS / 1000;
183
+ return cookie(SESSION_COOKIE, token, { secret, request, maxAge });
184
+ }
185
+ /** How old a session cookie gets before a response renews it: a day. */
186
+ const ROLL_MS = 24 * 60 * 60_000;
187
+ /**
188
+ * The wrap around every route renewing the session cookie a request signed in with once it is older than a day: the
189
+ * response sets it again with a fresh signed expiry, so a browser used within every 400 days stays signed in. Not when
190
+ * the route sets a cookie itself, nor for an ephemeral session's (it has no expiry) or a token that no longer
191
+ * authenticates.
192
+ */
193
+ function rollingCookie(secret, authenticate) {
194
+ return {
195
+ name: "chord.app.rolling-cookie",
196
+ phase: "headers",
197
+ scope: "all",
198
+ wrap: async (request, next, ctx) => {
199
+ const response = await next(request);
200
+ if (ctx.principal === undefined || Object.keys(response.headers ?? {}).some(isSetCookie))
201
+ return response;
202
+ const signed = readSignedCookie(request, SESSION_COOKIE, secret);
203
+ if (signed?.expires === undefined || signed.expires - Date.now() > SESSION_IDLE_MS - ROLL_MS)
204
+ return response;
205
+ if (authenticate(signed.value, ctx) === undefined)
206
+ return response;
207
+ const renewed = sessionCookie(signed.value, "browser", request, secret);
208
+ return { ...response, headers: { ...response.headers, "Set-Cookie": renewed } };
209
+ },
210
+ };
211
+ }
212
+ /** Whether a header name is `Set-Cookie` (any case). */
213
+ function isSetCookie(name) {
214
+ return name.toLowerCase() === "set-cookie";
215
+ }
216
+ /** The token of an `Authorization: Bearer <token>` header. */
217
+ function bearerToken(request) {
218
+ const header = request.headers.get("authorization");
219
+ const match = header === null ? null : /^Bearer\s+(\S+)$/i.exec(header);
220
+ return match?.[1];
221
+ }
222
+ //# sourceMappingURL=sessions.js.map