@earendil-works/chord 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (820) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +79 -14
  3. package/dist/cell.d.ts +7 -7
  4. package/dist/cell.d.ts.map +1 -1
  5. package/dist/cell.js.map +1 -1
  6. package/dist/context/index.d.ts +1 -1
  7. package/dist/context/index.d.ts.map +1 -1
  8. package/dist/context/index.js +1 -1
  9. package/dist/context/index.js.map +1 -1
  10. package/dist/contract.d.ts +51 -52
  11. package/dist/contract.d.ts.map +1 -1
  12. package/dist/contract.js +19 -24
  13. package/dist/contract.js.map +1 -1
  14. package/dist/delta/apply-immutable-trusted.js +3 -4
  15. package/dist/delta/apply-immutable-trusted.js.map +1 -1
  16. package/dist/delta/diff.d.ts.map +1 -1
  17. package/dist/delta/diff.js +5 -3
  18. package/dist/delta/diff.js.map +1 -1
  19. package/dist/delta/index.d.ts +9 -1
  20. package/dist/delta/index.d.ts.map +1 -1
  21. package/dist/delta/index.js +15 -11
  22. package/dist/delta/index.js.map +1 -1
  23. package/dist/delta/pending.d.ts +36 -0
  24. package/dist/delta/pending.d.ts.map +1 -0
  25. package/dist/delta/pending.js +143 -0
  26. package/dist/delta/pending.js.map +1 -0
  27. package/dist/delta/tracker.d.ts +12 -0
  28. package/dist/delta/tracker.d.ts.map +1 -1
  29. package/dist/delta/tracker.js +109 -39
  30. package/dist/delta/tracker.js.map +1 -1
  31. package/dist/host.d.ts.map +1 -1
  32. package/dist/host.js +9 -7
  33. package/dist/host.js.map +1 -1
  34. package/dist/index.d.ts +1 -0
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +1 -0
  37. package/dist/index.js.map +1 -1
  38. package/dist/next/contracts/accepts.d.ts +81 -0
  39. package/dist/next/contracts/accepts.d.ts.map +1 -0
  40. package/dist/next/contracts/accepts.js +123 -0
  41. package/dist/next/contracts/accepts.js.map +1 -0
  42. package/dist/next/contracts/contract.d.ts +121 -0
  43. package/dist/next/contracts/contract.d.ts.map +1 -0
  44. package/dist/next/contracts/contract.js +50 -0
  45. package/dist/next/contracts/contract.js.map +1 -0
  46. package/dist/next/contracts/declare.d.ts +107 -0
  47. package/dist/next/contracts/declare.d.ts.map +1 -0
  48. package/dist/next/contracts/declare.js +136 -0
  49. package/dist/next/contracts/declare.js.map +1 -0
  50. package/dist/next/contracts/evolve.d.ts +92 -0
  51. package/dist/next/contracts/evolve.d.ts.map +1 -0
  52. package/dist/next/contracts/evolve.js +179 -0
  53. package/dist/next/contracts/evolve.js.map +1 -0
  54. package/dist/next/contracts/fingerprint.d.ts +16 -0
  55. package/dist/next/contracts/fingerprint.d.ts.map +1 -0
  56. package/dist/next/contracts/fingerprint.js +50 -0
  57. package/dist/next/contracts/fingerprint.js.map +1 -0
  58. package/dist/next/contracts/history.d.ts +71 -0
  59. package/dist/next/contracts/history.d.ts.map +1 -0
  60. package/dist/next/contracts/history.js +3 -0
  61. package/dist/next/contracts/history.js.map +1 -0
  62. package/dist/next/contracts/host-kind.d.ts +40 -0
  63. package/dist/next/contracts/host-kind.d.ts.map +1 -0
  64. package/dist/next/contracts/host-kind.js +37 -0
  65. package/dist/next/contracts/host-kind.js.map +1 -0
  66. package/dist/next/contracts/index.d.ts +7 -0
  67. package/dist/next/contracts/index.d.ts.map +1 -0
  68. package/dist/next/contracts/index.js +6 -0
  69. package/dist/next/contracts/index.js.map +1 -0
  70. package/dist/next/contracts/internal.d.ts +10 -0
  71. package/dist/next/contracts/internal.d.ts.map +1 -0
  72. package/dist/next/contracts/internal.js +9 -0
  73. package/dist/next/contracts/internal.js.map +1 -0
  74. package/dist/next/contracts/names.d.ts +3 -0
  75. package/dist/next/contracts/names.d.ts.map +1 -0
  76. package/dist/next/contracts/names.js +13 -0
  77. package/dist/next/contracts/names.js.map +1 -0
  78. package/dist/next/contracts/params.d.ts +28 -0
  79. package/dist/next/contracts/params.d.ts.map +1 -0
  80. package/dist/next/contracts/params.js +50 -0
  81. package/dist/next/contracts/params.js.map +1 -0
  82. package/dist/next/contracts/schema.d.ts +102 -0
  83. package/dist/next/contracts/schema.d.ts.map +1 -0
  84. package/dist/next/contracts/schema.js +103 -0
  85. package/dist/next/contracts/schema.js.map +1 -0
  86. package/dist/next/contracts/snapshot.d.ts +16 -0
  87. package/dist/next/contracts/snapshot.d.ts.map +1 -0
  88. package/dist/next/contracts/snapshot.js +167 -0
  89. package/dist/next/contracts/snapshot.js.map +1 -0
  90. package/dist/next/data/args.d.ts +50 -0
  91. package/dist/next/data/args.d.ts.map +1 -0
  92. package/dist/next/data/args.js +83 -0
  93. package/dist/next/data/args.js.map +1 -0
  94. package/dist/next/data/errors.d.ts +73 -0
  95. package/dist/next/data/errors.d.ts.map +1 -0
  96. package/dist/next/data/errors.js +107 -0
  97. package/dist/next/data/errors.js.map +1 -0
  98. package/dist/next/data/failure.d.ts +26 -0
  99. package/dist/next/data/failure.d.ts.map +1 -0
  100. package/dist/next/data/failure.js +72 -0
  101. package/dist/next/data/failure.js.map +1 -0
  102. package/dist/next/data/index.d.ts +4 -0
  103. package/dist/next/data/index.d.ts.map +1 -0
  104. package/dist/next/data/index.js +4 -0
  105. package/dist/next/data/index.js.map +1 -0
  106. package/dist/next/data/internal.d.ts +7 -0
  107. package/dist/next/data/internal.d.ts.map +1 -0
  108. package/dist/next/data/internal.js +8 -0
  109. package/dist/next/data/internal.js.map +1 -0
  110. package/dist/next/data/params.d.ts +20 -0
  111. package/dist/next/data/params.d.ts.map +1 -0
  112. package/dist/next/data/params.js +31 -0
  113. package/dist/next/data/params.js.map +1 -0
  114. package/dist/next/data/principal.d.ts +17 -0
  115. package/dist/next/data/principal.d.ts.map +1 -0
  116. package/dist/next/data/principal.js +41 -0
  117. package/dist/next/data/principal.js.map +1 -0
  118. package/dist/next/data/validator.d.ts +12 -0
  119. package/dist/next/data/validator.d.ts.map +1 -0
  120. package/dist/next/data/validator.js +34 -0
  121. package/dist/next/data/validator.js.map +1 -0
  122. package/dist/next/documents/address-source.d.ts +20 -0
  123. package/dist/next/documents/address-source.d.ts.map +1 -0
  124. package/dist/next/documents/address-source.js +44 -0
  125. package/dist/next/documents/address-source.js.map +1 -0
  126. package/dist/next/documents/definition.d.ts +84 -0
  127. package/dist/next/documents/definition.d.ts.map +1 -0
  128. package/dist/next/documents/definition.js +73 -0
  129. package/dist/next/documents/definition.js.map +1 -0
  130. package/dist/next/documents/documents.d.ts +106 -0
  131. package/dist/next/documents/documents.d.ts.map +1 -0
  132. package/dist/next/documents/documents.js +224 -0
  133. package/dist/next/documents/documents.js.map +1 -0
  134. package/dist/next/documents/fence.d.ts +9 -0
  135. package/dist/next/documents/fence.d.ts.map +1 -0
  136. package/dist/next/documents/fence.js +15 -0
  137. package/dist/next/documents/fence.js.map +1 -0
  138. package/dist/next/documents/handles.d.ts +76 -0
  139. package/dist/next/documents/handles.d.ts.map +1 -0
  140. package/dist/next/documents/handles.js +66 -0
  141. package/dist/next/documents/handles.js.map +1 -0
  142. package/dist/next/documents/index.d.ts +4 -0
  143. package/dist/next/documents/index.d.ts.map +1 -0
  144. package/dist/next/documents/index.js +3 -0
  145. package/dist/next/documents/index.js.map +1 -0
  146. package/dist/next/documents/internal.d.ts +9 -0
  147. package/dist/next/documents/internal.d.ts.map +1 -0
  148. package/dist/next/documents/internal.js +9 -0
  149. package/dist/next/documents/internal.js.map +1 -0
  150. package/dist/next/documents/keyed-slot.d.ts +103 -0
  151. package/dist/next/documents/keyed-slot.d.ts.map +1 -0
  152. package/dist/next/documents/keyed-slot.js +395 -0
  153. package/dist/next/documents/keyed-slot.js.map +1 -0
  154. package/dist/next/documents/line.d.ts +7 -0
  155. package/dist/next/documents/line.d.ts.map +1 -0
  156. package/dist/next/documents/line.js +14 -0
  157. package/dist/next/documents/line.js.map +1 -0
  158. package/dist/next/documents/persistence.d.ts +104 -0
  159. package/dist/next/documents/persistence.d.ts.map +1 -0
  160. package/dist/next/documents/persistence.js +128 -0
  161. package/dist/next/documents/persistence.js.map +1 -0
  162. package/dist/next/documents/residency.d.ts +31 -0
  163. package/dist/next/documents/residency.d.ts.map +1 -0
  164. package/dist/next/documents/residency.js +93 -0
  165. package/dist/next/documents/residency.js.map +1 -0
  166. package/dist/next/documents/slot.d.ts +109 -0
  167. package/dist/next/documents/slot.d.ts.map +1 -0
  168. package/dist/next/documents/slot.js +181 -0
  169. package/dist/next/documents/slot.js.map +1 -0
  170. package/dist/next/documents/transaction.d.ts +133 -0
  171. package/dist/next/documents/transaction.d.ts.map +1 -0
  172. package/dist/next/documents/transaction.js +409 -0
  173. package/dist/next/documents/transaction.js.map +1 -0
  174. package/dist/next/host/activity.d.ts +31 -0
  175. package/dist/next/host/activity.d.ts.map +1 -0
  176. package/dist/next/host/activity.js +40 -0
  177. package/dist/next/host/activity.js.map +1 -0
  178. package/dist/next/host/adapted.d.ts +49 -0
  179. package/dist/next/host/adapted.d.ts.map +1 -0
  180. package/dist/next/host/adapted.js +214 -0
  181. package/dist/next/host/adapted.js.map +1 -0
  182. package/dist/next/host/attempt.d.ts +278 -0
  183. package/dist/next/host/attempt.d.ts.map +1 -0
  184. package/dist/next/host/attempt.js +1072 -0
  185. package/dist/next/host/attempt.js.map +1 -0
  186. package/dist/next/host/backoff.d.ts +29 -0
  187. package/dist/next/host/backoff.d.ts.map +1 -0
  188. package/dist/next/host/backoff.js +69 -0
  189. package/dist/next/host/backoff.js.map +1 -0
  190. package/dist/next/host/ctx.d.ts +47 -0
  191. package/dist/next/host/ctx.d.ts.map +1 -0
  192. package/dist/next/host/ctx.js +108 -0
  193. package/dist/next/host/ctx.js.map +1 -0
  194. package/dist/next/host/deadline.d.ts +12 -0
  195. package/dist/next/host/deadline.d.ts.map +1 -0
  196. package/dist/next/host/deadline.js +40 -0
  197. package/dist/next/host/deadline.js.map +1 -0
  198. package/dist/next/host/dependencies.d.ts +65 -0
  199. package/dist/next/host/dependencies.d.ts.map +1 -0
  200. package/dist/next/host/dependencies.js +115 -0
  201. package/dist/next/host/dependencies.js.map +1 -0
  202. package/dist/next/host/destination.d.ts +48 -0
  203. package/dist/next/host/destination.d.ts.map +1 -0
  204. package/dist/next/host/destination.js +101 -0
  205. package/dist/next/host/destination.js.map +1 -0
  206. package/dist/next/host/facet.d.ts +79 -0
  207. package/dist/next/host/facet.d.ts.map +1 -0
  208. package/dist/next/host/facet.js +55 -0
  209. package/dist/next/host/facet.js.map +1 -0
  210. package/dist/next/host/follow.d.ts +52 -0
  211. package/dist/next/host/follow.d.ts.map +1 -0
  212. package/dist/next/host/follow.js +207 -0
  213. package/dist/next/host/follow.js.map +1 -0
  214. package/dist/next/host/host.d.ts +495 -0
  215. package/dist/next/host/host.d.ts.map +1 -0
  216. package/dist/next/host/host.js +1075 -0
  217. package/dist/next/host/host.js.map +1 -0
  218. package/dist/next/host/index.d.ts +17 -0
  219. package/dist/next/host/index.d.ts.map +1 -0
  220. package/dist/next/host/index.js +6 -0
  221. package/dist/next/host/index.js.map +1 -0
  222. package/dist/next/host/internal.d.ts +10 -0
  223. package/dist/next/host/internal.d.ts.map +1 -0
  224. package/dist/next/host/internal.js +8 -0
  225. package/dist/next/host/internal.js.map +1 -0
  226. package/dist/next/host/members.d.ts +50 -0
  227. package/dist/next/host/members.d.ts.map +1 -0
  228. package/dist/next/host/members.js +107 -0
  229. package/dist/next/host/members.js.map +1 -0
  230. package/dist/next/host/native.d.ts +55 -0
  231. package/dist/next/host/native.d.ts.map +1 -0
  232. package/dist/next/host/native.js +92 -0
  233. package/dist/next/host/native.js.map +1 -0
  234. package/dist/next/host/object.d.ts +290 -0
  235. package/dist/next/host/object.d.ts.map +1 -0
  236. package/dist/next/host/object.js +1127 -0
  237. package/dist/next/host/object.js.map +1 -0
  238. package/dist/next/host/parked.d.ts +23 -0
  239. package/dist/next/host/parked.d.ts.map +1 -0
  240. package/dist/next/host/parked.js +79 -0
  241. package/dist/next/host/parked.js.map +1 -0
  242. package/dist/next/host/presence.d.ts +34 -0
  243. package/dist/next/host/presence.d.ts.map +1 -0
  244. package/dist/next/host/presence.js +117 -0
  245. package/dist/next/host/presence.js.map +1 -0
  246. package/dist/next/host/ref-state.d.ts +53 -0
  247. package/dist/next/host/ref-state.d.ts.map +1 -0
  248. package/dist/next/host/ref-state.js +83 -0
  249. package/dist/next/host/ref-state.js.map +1 -0
  250. package/dist/next/host/reference-keys.d.ts +36 -0
  251. package/dist/next/host/reference-keys.d.ts.map +1 -0
  252. package/dist/next/host/reference-keys.js +168 -0
  253. package/dist/next/host/reference-keys.js.map +1 -0
  254. package/dist/next/host/reference-source.d.ts +65 -0
  255. package/dist/next/host/reference-source.d.ts.map +1 -0
  256. package/dist/next/host/reference-source.js +285 -0
  257. package/dist/next/host/reference-source.js.map +1 -0
  258. package/dist/next/host/reference.d.ts +308 -0
  259. package/dist/next/host/reference.d.ts.map +1 -0
  260. package/dist/next/host/reference.js +775 -0
  261. package/dist/next/host/reference.js.map +1 -0
  262. package/dist/next/host/retry-on.d.ts +28 -0
  263. package/dist/next/host/retry-on.d.ts.map +1 -0
  264. package/dist/next/host/retry-on.js +52 -0
  265. package/dist/next/host/retry-on.js.map +1 -0
  266. package/dist/next/host/revocation.d.ts +16 -0
  267. package/dist/next/host/revocation.d.ts.map +1 -0
  268. package/dist/next/host/revocation.js +27 -0
  269. package/dist/next/host/revocation.js.map +1 -0
  270. package/dist/next/host/root.d.ts +27 -0
  271. package/dist/next/host/root.d.ts.map +1 -0
  272. package/dist/next/host/root.js +68 -0
  273. package/dist/next/host/root.js.map +1 -0
  274. package/dist/next/host/route.d.ts +64 -0
  275. package/dist/next/host/route.d.ts.map +1 -0
  276. package/dist/next/host/route.js +190 -0
  277. package/dist/next/host/route.js.map +1 -0
  278. package/dist/next/host/routines.d.ts +76 -0
  279. package/dist/next/host/routines.d.ts.map +1 -0
  280. package/dist/next/host/routines.js +350 -0
  281. package/dist/next/host/routines.js.map +1 -0
  282. package/dist/next/host/sleep.d.ts +9 -0
  283. package/dist/next/host/sleep.d.ts.map +1 -0
  284. package/dist/next/host/sleep.js +40 -0
  285. package/dist/next/host/sleep.js.map +1 -0
  286. package/dist/next/host/staging.d.ts +94 -0
  287. package/dist/next/host/staging.d.ts.map +1 -0
  288. package/dist/next/host/staging.js +302 -0
  289. package/dist/next/host/staging.js.map +1 -0
  290. package/dist/next/host/unbound.d.ts +30 -0
  291. package/dist/next/host/unbound.d.ts.map +1 -0
  292. package/dist/next/host/unbound.js +67 -0
  293. package/dist/next/host/unbound.js.map +1 -0
  294. package/dist/next/host/uuid.d.ts +3 -0
  295. package/dist/next/host/uuid.d.ts.map +1 -0
  296. package/dist/next/host/uuid.js +38 -0
  297. package/dist/next/host/uuid.js.map +1 -0
  298. package/dist/next/index.d.ts +28 -0
  299. package/dist/next/index.d.ts.map +1 -0
  300. package/dist/next/index.js +18 -0
  301. package/dist/next/index.js.map +1 -0
  302. package/dist/next/jobs/definition.d.ts +96 -0
  303. package/dist/next/jobs/definition.d.ts.map +1 -0
  304. package/dist/next/jobs/definition.js +83 -0
  305. package/dist/next/jobs/definition.js.map +1 -0
  306. package/dist/next/jobs/index.d.ts +5 -0
  307. package/dist/next/jobs/index.d.ts.map +1 -0
  308. package/dist/next/jobs/index.js +3 -0
  309. package/dist/next/jobs/index.js.map +1 -0
  310. package/dist/next/jobs/internal.d.ts +3 -0
  311. package/dist/next/jobs/internal.d.ts.map +1 -0
  312. package/dist/next/jobs/internal.js +4 -0
  313. package/dist/next/jobs/internal.js.map +1 -0
  314. package/dist/next/jobs/job.d.ts +152 -0
  315. package/dist/next/jobs/job.d.ts.map +1 -0
  316. package/dist/next/jobs/job.js +320 -0
  317. package/dist/next/jobs/job.js.map +1 -0
  318. package/dist/next/jobs/persisted.d.ts +38 -0
  319. package/dist/next/jobs/persisted.d.ts.map +1 -0
  320. package/dist/next/jobs/persisted.js +95 -0
  321. package/dist/next/jobs/persisted.js.map +1 -0
  322. package/dist/next/jobs/records.d.ts +231 -0
  323. package/dist/next/jobs/records.d.ts.map +1 -0
  324. package/dist/next/jobs/records.js +869 -0
  325. package/dist/next/jobs/records.js.map +1 -0
  326. package/dist/next/jobs/run-states.d.ts +69 -0
  327. package/dist/next/jobs/run-states.d.ts.map +1 -0
  328. package/dist/next/jobs/run-states.js +228 -0
  329. package/dist/next/jobs/run-states.js.map +1 -0
  330. package/dist/next/jobs/run.d.ts +113 -0
  331. package/dist/next/jobs/run.d.ts.map +1 -0
  332. package/dist/next/jobs/run.js +200 -0
  333. package/dist/next/jobs/run.js.map +1 -0
  334. package/dist/next/jobs/running.d.ts +44 -0
  335. package/dist/next/jobs/running.d.ts.map +1 -0
  336. package/dist/next/jobs/running.js +117 -0
  337. package/dist/next/jobs/running.js.map +1 -0
  338. package/dist/next/jobs/stored.d.ts +63 -0
  339. package/dist/next/jobs/stored.d.ts.map +1 -0
  340. package/dist/next/jobs/stored.js +55 -0
  341. package/dist/next/jobs/stored.js.map +1 -0
  342. package/dist/next/link/binary.d.ts +4 -0
  343. package/dist/next/link/binary.d.ts.map +1 -0
  344. package/dist/next/link/binary.js +534 -0
  345. package/dist/next/link/binary.js.map +1 -0
  346. package/dist/next/link/channel.d.ts +63 -0
  347. package/dist/next/link/channel.d.ts.map +1 -0
  348. package/dist/next/link/channel.js +202 -0
  349. package/dist/next/link/channel.js.map +1 -0
  350. package/dist/next/link/errors.d.ts +7 -0
  351. package/dist/next/link/errors.d.ts.map +1 -0
  352. package/dist/next/link/errors.js +21 -0
  353. package/dist/next/link/errors.js.map +1 -0
  354. package/dist/next/link/index.d.ts +8 -0
  355. package/dist/next/link/index.d.ts.map +1 -0
  356. package/dist/next/link/index.js +8 -0
  357. package/dist/next/link/index.js.map +1 -0
  358. package/dist/next/link/internal.d.ts +9 -0
  359. package/dist/next/link/internal.d.ts.map +1 -0
  360. package/dist/next/link/internal.js +10 -0
  361. package/dist/next/link/internal.js.map +1 -0
  362. package/dist/next/link/ipc.d.ts +22 -0
  363. package/dist/next/link/ipc.d.ts.map +1 -0
  364. package/dist/next/link/ipc.js +64 -0
  365. package/dist/next/link/ipc.js.map +1 -0
  366. package/dist/next/link/link.d.ts +34 -0
  367. package/dist/next/link/link.d.ts.map +1 -0
  368. package/dist/next/link/link.js +87 -0
  369. package/dist/next/link/link.js.map +1 -0
  370. package/dist/next/link/message.d.ts +249 -0
  371. package/dist/next/link/message.d.ts.map +1 -0
  372. package/dist/next/link/message.js +123 -0
  373. package/dist/next/link/message.js.map +1 -0
  374. package/dist/next/link/part.d.ts +80 -0
  375. package/dist/next/link/part.d.ts.map +1 -0
  376. package/dist/next/link/part.js +164 -0
  377. package/dist/next/link/part.js.map +1 -0
  378. package/dist/next/link/text.d.ts +6 -0
  379. package/dist/next/link/text.d.ts.map +1 -0
  380. package/dist/next/link/text.js +335 -0
  381. package/dist/next/link/text.js.map +1 -0
  382. package/dist/next/link/values.d.ts +40 -0
  383. package/dist/next/link/values.d.ts.map +1 -0
  384. package/dist/next/link/values.js +117 -0
  385. package/dist/next/link/values.js.map +1 -0
  386. package/dist/next/link/websocket.d.ts +26 -0
  387. package/dist/next/link/websocket.d.ts.map +1 -0
  388. package/dist/next/link/websocket.js +91 -0
  389. package/dist/next/link/websocket.js.map +1 -0
  390. package/dist/next/registries/contribution.d.ts +50 -0
  391. package/dist/next/registries/contribution.d.ts.map +1 -0
  392. package/dist/next/registries/contribution.js +129 -0
  393. package/dist/next/registries/contribution.js.map +1 -0
  394. package/dist/next/registries/entries.d.ts +18 -0
  395. package/dist/next/registries/entries.d.ts.map +1 -0
  396. package/dist/next/registries/entries.js +42 -0
  397. package/dist/next/registries/entries.js.map +1 -0
  398. package/dist/next/registries/index.d.ts +3 -0
  399. package/dist/next/registries/index.d.ts.map +1 -0
  400. package/dist/next/registries/index.js +5 -0
  401. package/dist/next/registries/index.js.map +1 -0
  402. package/dist/next/registries/internal.d.ts +4 -0
  403. package/dist/next/registries/internal.d.ts.map +1 -0
  404. package/dist/next/registries/internal.js +5 -0
  405. package/dist/next/registries/internal.js.map +1 -0
  406. package/dist/next/registries/record.d.ts +94 -0
  407. package/dist/next/registries/record.d.ts.map +1 -0
  408. package/dist/next/registries/record.js +253 -0
  409. package/dist/next/registries/record.js.map +1 -0
  410. package/dist/next/registries/registry.d.ts +74 -0
  411. package/dist/next/registries/registry.d.ts.map +1 -0
  412. package/dist/next/registries/registry.js +14 -0
  413. package/dist/next/registries/registry.js.map +1 -0
  414. package/dist/next/registries/value.d.ts +48 -0
  415. package/dist/next/registries/value.d.ts.map +1 -0
  416. package/dist/next/registries/value.js +199 -0
  417. package/dist/next/registries/value.js.map +1 -0
  418. package/dist/next/remote/calls.d.ts +25 -0
  419. package/dist/next/remote/calls.d.ts.map +1 -0
  420. package/dist/next/remote/calls.js +62 -0
  421. package/dist/next/remote/calls.js.map +1 -0
  422. package/dist/next/remote/consumer.d.ts +42 -0
  423. package/dist/next/remote/consumer.d.ts.map +1 -0
  424. package/dist/next/remote/consumer.js +343 -0
  425. package/dist/next/remote/consumer.js.map +1 -0
  426. package/dist/next/remote/hold.d.ts +130 -0
  427. package/dist/next/remote/hold.d.ts.map +1 -0
  428. package/dist/next/remote/hold.js +537 -0
  429. package/dist/next/remote/hold.js.map +1 -0
  430. package/dist/next/remote/host-link.d.ts +77 -0
  431. package/dist/next/remote/host-link.d.ts.map +1 -0
  432. package/dist/next/remote/host-link.js +182 -0
  433. package/dist/next/remote/host-link.js.map +1 -0
  434. package/dist/next/remote/internal.d.ts +6 -0
  435. package/dist/next/remote/internal.d.ts.map +1 -0
  436. package/dist/next/remote/internal.js +6 -0
  437. package/dist/next/remote/internal.js.map +1 -0
  438. package/dist/next/remote/path.d.ts +46 -0
  439. package/dist/next/remote/path.d.ts.map +1 -0
  440. package/dist/next/remote/path.js +73 -0
  441. package/dist/next/remote/path.js.map +1 -0
  442. package/dist/next/remote/provider.d.ts +76 -0
  443. package/dist/next/remote/provider.d.ts.map +1 -0
  444. package/dist/next/remote/provider.js +506 -0
  445. package/dist/next/remote/provider.js.map +1 -0
  446. package/dist/next/remote/relay.d.ts +58 -0
  447. package/dist/next/remote/relay.d.ts.map +1 -0
  448. package/dist/next/remote/relay.js +117 -0
  449. package/dist/next/remote/relay.js.map +1 -0
  450. package/dist/next/remote/remote-object.d.ts +133 -0
  451. package/dist/next/remote/remote-object.d.ts.map +1 -0
  452. package/dist/next/remote/remote-object.js +411 -0
  453. package/dist/next/remote/remote-object.js.map +1 -0
  454. package/dist/next/remote/replica.d.ts +59 -0
  455. package/dist/next/remote/replica.d.ts.map +1 -0
  456. package/dist/next/remote/replica.js +125 -0
  457. package/dist/next/remote/replica.js.map +1 -0
  458. package/dist/next/state/batch.d.ts +64 -0
  459. package/dist/next/state/batch.d.ts.map +1 -0
  460. package/dist/next/state/batch.js +163 -0
  461. package/dist/next/state/batch.js.map +1 -0
  462. package/dist/next/state/derive.d.ts +52 -0
  463. package/dist/next/state/derive.d.ts.map +1 -0
  464. package/dist/next/state/derive.js +182 -0
  465. package/dist/next/state/derive.js.map +1 -0
  466. package/dist/next/state/index.d.ts +6 -0
  467. package/dist/next/state/index.d.ts.map +1 -0
  468. package/dist/next/state/index.js +4 -0
  469. package/dist/next/state/index.js.map +1 -0
  470. package/dist/next/state/internal.d.ts +6 -0
  471. package/dist/next/state/internal.d.ts.map +1 -0
  472. package/dist/next/state/internal.js +8 -0
  473. package/dist/next/state/internal.js.map +1 -0
  474. package/dist/next/state/native-source.d.ts +106 -0
  475. package/dist/next/state/native-source.d.ts.map +1 -0
  476. package/dist/next/state/native-source.js +240 -0
  477. package/dist/next/state/native-source.js.map +1 -0
  478. package/dist/next/state/watchable.d.ts +114 -0
  479. package/dist/next/state/watchable.d.ts.map +1 -0
  480. package/dist/next/state/watchable.js +156 -0
  481. package/dist/next/state/watchable.js.map +1 -0
  482. package/dist/next/state/writable.d.ts +32 -0
  483. package/dist/next/state/writable.d.ts.map +1 -0
  484. package/dist/next/state/writable.js +49 -0
  485. package/dist/next/state/writable.js.map +1 -0
  486. package/dist/next/store/adapter.d.ts +67 -0
  487. package/dist/next/store/adapter.d.ts.map +1 -0
  488. package/dist/next/store/adapter.js +118 -0
  489. package/dist/next/store/adapter.js.map +1 -0
  490. package/dist/next/store/allocator.d.ts +17 -0
  491. package/dist/next/store/allocator.d.ts.map +1 -0
  492. package/dist/next/store/allocator.js +30 -0
  493. package/dist/next/store/allocator.js.map +1 -0
  494. package/dist/next/store/applier.d.ts +8 -0
  495. package/dist/next/store/applier.d.ts.map +1 -0
  496. package/dist/next/store/applier.js +375 -0
  497. package/dist/next/store/applier.js.map +1 -0
  498. package/dist/next/store/apply-batch.d.ts +12 -0
  499. package/dist/next/store/apply-batch.d.ts.map +1 -0
  500. package/dist/next/store/apply-batch.js +83 -0
  501. package/dist/next/store/apply-batch.js.map +1 -0
  502. package/dist/next/store/archive.d.ts +32 -0
  503. package/dist/next/store/archive.d.ts.map +1 -0
  504. package/dist/next/store/archive.js +129 -0
  505. package/dist/next/store/archive.js.map +1 -0
  506. package/dist/next/store/backend.d.ts +10 -0
  507. package/dist/next/store/backend.d.ts.map +1 -0
  508. package/dist/next/store/backend.js +15 -0
  509. package/dist/next/store/backend.js.map +1 -0
  510. package/dist/next/store/catalog.d.ts +24 -0
  511. package/dist/next/store/catalog.d.ts.map +1 -0
  512. package/dist/next/store/catalog.js +17 -0
  513. package/dist/next/store/catalog.js.map +1 -0
  514. package/dist/next/store/claims.d.ts +23 -0
  515. package/dist/next/store/claims.d.ts.map +1 -0
  516. package/dist/next/store/claims.js +65 -0
  517. package/dist/next/store/claims.js.map +1 -0
  518. package/dist/next/store/columns.d.ts +77 -0
  519. package/dist/next/store/columns.d.ts.map +1 -0
  520. package/dist/next/store/columns.js +77 -0
  521. package/dist/next/store/columns.js.map +1 -0
  522. package/dist/next/store/engine.d.ts +176 -0
  523. package/dist/next/store/engine.d.ts.map +1 -0
  524. package/dist/next/store/engine.js +283 -0
  525. package/dist/next/store/engine.js.map +1 -0
  526. package/dist/next/store/evaluate.d.ts +17 -0
  527. package/dist/next/store/evaluate.d.ts.map +1 -0
  528. package/dist/next/store/evaluate.js +128 -0
  529. package/dist/next/store/evaluate.js.map +1 -0
  530. package/dist/next/store/export.d.ts +17 -0
  531. package/dist/next/store/export.d.ts.map +1 -0
  532. package/dist/next/store/export.js +200 -0
  533. package/dist/next/store/export.js.map +1 -0
  534. package/dist/next/store/expression.d.ts +150 -0
  535. package/dist/next/store/expression.d.ts.map +1 -0
  536. package/dist/next/store/expression.js +268 -0
  537. package/dist/next/store/expression.js.map +1 -0
  538. package/dist/next/store/import.d.ts +10 -0
  539. package/dist/next/store/import.d.ts.map +1 -0
  540. package/dist/next/store/import.js +276 -0
  541. package/dist/next/store/import.js.map +1 -0
  542. package/dist/next/store/index.d.ts +16 -0
  543. package/dist/next/store/index.d.ts.map +1 -0
  544. package/dist/next/store/index.js +13 -0
  545. package/dist/next/store/index.js.map +1 -0
  546. package/dist/next/store/json-column.d.ts +33 -0
  547. package/dist/next/store/json-column.d.ts.map +1 -0
  548. package/dist/next/store/json-column.js +61 -0
  549. package/dist/next/store/json-column.js.map +1 -0
  550. package/dist/next/store/jsonl.d.ts +9 -0
  551. package/dist/next/store/jsonl.d.ts.map +1 -0
  552. package/dist/next/store/jsonl.js +61 -0
  553. package/dist/next/store/jsonl.js.map +1 -0
  554. package/dist/next/store/outbox.d.ts +26 -0
  555. package/dist/next/store/outbox.d.ts.map +1 -0
  556. package/dist/next/store/outbox.js +80 -0
  557. package/dist/next/store/outbox.js.map +1 -0
  558. package/dist/next/store/query.d.ts +39 -0
  559. package/dist/next/store/query.d.ts.map +1 -0
  560. package/dist/next/store/query.js +97 -0
  561. package/dist/next/store/query.js.map +1 -0
  562. package/dist/next/store/refusal.d.ts +15 -0
  563. package/dist/next/store/refusal.d.ts.map +1 -0
  564. package/dist/next/store/refusal.js +36 -0
  565. package/dist/next/store/refusal.js.map +1 -0
  566. package/dist/next/store/rows.d.ts +80 -0
  567. package/dist/next/store/rows.d.ts.map +1 -0
  568. package/dist/next/store/rows.js +183 -0
  569. package/dist/next/store/rows.js.map +1 -0
  570. package/dist/next/store/schema.d.ts +25 -0
  571. package/dist/next/store/schema.d.ts.map +1 -0
  572. package/dist/next/store/schema.js +115 -0
  573. package/dist/next/store/schema.js.map +1 -0
  574. package/dist/next/store/sql.d.ts +73 -0
  575. package/dist/next/store/sql.d.ts.map +1 -0
  576. package/dist/next/store/sql.js +234 -0
  577. package/dist/next/store/sql.js.map +1 -0
  578. package/dist/next/store/step.d.ts +48 -0
  579. package/dist/next/store/step.d.ts.map +1 -0
  580. package/dist/next/store/step.js +50 -0
  581. package/dist/next/store/step.js.map +1 -0
  582. package/dist/next/store/store.d.ts +161 -0
  583. package/dist/next/store/store.d.ts.map +1 -0
  584. package/dist/next/store/store.js +627 -0
  585. package/dist/next/store/store.js.map +1 -0
  586. package/dist/next/store/table-changes.d.ts +29 -0
  587. package/dist/next/store/table-changes.d.ts.map +1 -0
  588. package/dist/next/store/table-changes.js +102 -0
  589. package/dist/next/store/table-changes.js.map +1 -0
  590. package/dist/next/store/table-evolve.d.ts +74 -0
  591. package/dist/next/store/table-evolve.d.ts.map +1 -0
  592. package/dist/next/store/table-evolve.js +201 -0
  593. package/dist/next/store/table-evolve.js.map +1 -0
  594. package/dist/next/store/table-handle.d.ts +67 -0
  595. package/dist/next/store/table-handle.d.ts.map +1 -0
  596. package/dist/next/store/table-handle.js +101 -0
  597. package/dist/next/store/table-handle.js.map +1 -0
  598. package/dist/next/store/table-history.d.ts +75 -0
  599. package/dist/next/store/table-history.d.ts.map +1 -0
  600. package/dist/next/store/table-history.js +42 -0
  601. package/dist/next/store/table-history.js.map +1 -0
  602. package/dist/next/store/table-migration.d.ts +16 -0
  603. package/dist/next/store/table-migration.d.ts.map +1 -0
  604. package/dist/next/store/table-migration.js +202 -0
  605. package/dist/next/store/table-migration.js.map +1 -0
  606. package/dist/next/store/table-writes.d.ts +125 -0
  607. package/dist/next/store/table-writes.d.ts.map +1 -0
  608. package/dist/next/store/table-writes.js +165 -0
  609. package/dist/next/store/table-writes.js.map +1 -0
  610. package/dist/next/store/table.d.ts +80 -0
  611. package/dist/next/store/table.d.ts.map +1 -0
  612. package/dist/next/store/table.js +103 -0
  613. package/dist/next/store/table.js.map +1 -0
  614. package/dist/next/store/text.d.ts +14 -0
  615. package/dist/next/store/text.d.ts.map +1 -0
  616. package/dist/next/store/text.js +51 -0
  617. package/dist/next/store/text.js.map +1 -0
  618. package/dist/next/store/writes.d.ts +5 -0
  619. package/dist/next/store/writes.d.ts.map +1 -0
  620. package/dist/next/store/writes.js +4 -0
  621. package/dist/next/store/writes.js.map +1 -0
  622. package/dist/next-node/compression.d.ts +7 -0
  623. package/dist/next-node/compression.d.ts.map +1 -0
  624. package/dist/next-node/compression.js +24 -0
  625. package/dist/next-node/compression.js.map +1 -0
  626. package/dist/next-node/http/admission.d.ts +63 -0
  627. package/dist/next-node/http/admission.d.ts.map +1 -0
  628. package/dist/next-node/http/admission.js +134 -0
  629. package/dist/next-node/http/admission.js.map +1 -0
  630. package/dist/next-node/http/authenticate.d.ts +21 -0
  631. package/dist/next-node/http/authenticate.d.ts.map +1 -0
  632. package/dist/next-node/http/authenticate.js +34 -0
  633. package/dist/next-node/http/authenticate.js.map +1 -0
  634. package/dist/next-node/http/cookies.d.ts +24 -0
  635. package/dist/next-node/http/cookies.d.ts.map +1 -0
  636. package/dist/next-node/http/cookies.js +62 -0
  637. package/dist/next-node/http/cookies.js.map +1 -0
  638. package/dist/next-node/http/file.d.ts +23 -0
  639. package/dist/next-node/http/file.d.ts.map +1 -0
  640. package/dist/next-node/http/file.js +94 -0
  641. package/dist/next-node/http/file.js.map +1 -0
  642. package/dist/next-node/http/headers.d.ts +37 -0
  643. package/dist/next-node/http/headers.d.ts.map +1 -0
  644. package/dist/next-node/http/headers.js +129 -0
  645. package/dist/next-node/http/headers.js.map +1 -0
  646. package/dist/next-node/http/http.d.ts +100 -0
  647. package/dist/next-node/http/http.d.ts.map +1 -0
  648. package/dist/next-node/http/http.js +462 -0
  649. package/dist/next-node/http/http.js.map +1 -0
  650. package/dist/next-node/http/incoming.d.ts +19 -0
  651. package/dist/next-node/http/incoming.d.ts.map +1 -0
  652. package/dist/next-node/http/incoming.js +31 -0
  653. package/dist/next-node/http/incoming.js.map +1 -0
  654. package/dist/next-node/http/index.d.ts +11 -0
  655. package/dist/next-node/http/index.d.ts.map +1 -0
  656. package/dist/next-node/http/index.js +12 -0
  657. package/dist/next-node/http/index.js.map +1 -0
  658. package/dist/next-node/http/node.d.ts +78 -0
  659. package/dist/next-node/http/node.d.ts.map +1 -0
  660. package/dist/next-node/http/node.js +291 -0
  661. package/dist/next-node/http/node.js.map +1 -0
  662. package/dist/next-node/http/request.d.ts +54 -0
  663. package/dist/next-node/http/request.d.ts.map +1 -0
  664. package/dist/next-node/http/request.js +116 -0
  665. package/dist/next-node/http/request.js.map +1 -0
  666. package/dist/next-node/http/response.d.ts +63 -0
  667. package/dist/next-node/http/response.d.ts.map +1 -0
  668. package/dist/next-node/http/response.js +202 -0
  669. package/dist/next-node/http/response.js.map +1 -0
  670. package/dist/next-node/http/router.d.ts +114 -0
  671. package/dist/next-node/http/router.d.ts.map +1 -0
  672. package/dist/next-node/http/router.js +261 -0
  673. package/dist/next-node/http/router.js.map +1 -0
  674. package/dist/next-node/http/upgrades.d.ts +58 -0
  675. package/dist/next-node/http/upgrades.d.ts.map +1 -0
  676. package/dist/next-node/http/upgrades.js +184 -0
  677. package/dist/next-node/http/upgrades.js.map +1 -0
  678. package/dist/next-node/plugins/build.d.ts +57 -0
  679. package/dist/next-node/plugins/build.d.ts.map +1 -0
  680. package/dist/next-node/plugins/build.js +334 -0
  681. package/dist/next-node/plugins/build.js.map +1 -0
  682. package/dist/next-node/plugins/discover.d.ts +36 -0
  683. package/dist/next-node/plugins/discover.d.ts.map +1 -0
  684. package/dist/next-node/plugins/discover.js +91 -0
  685. package/dist/next-node/plugins/discover.js.map +1 -0
  686. package/dist/next-node/plugins/evaluate.d.ts +33 -0
  687. package/dist/next-node/plugins/evaluate.d.ts.map +1 -0
  688. package/dist/next-node/plugins/evaluate.js +98 -0
  689. package/dist/next-node/plugins/evaluate.js.map +1 -0
  690. package/dist/next-node/plugins/index.d.ts +9 -0
  691. package/dist/next-node/plugins/index.d.ts.map +1 -0
  692. package/dist/next-node/plugins/index.js +11 -0
  693. package/dist/next-node/plugins/index.js.map +1 -0
  694. package/dist/next-node/plugins/install.d.ts +13 -0
  695. package/dist/next-node/plugins/install.d.ts.map +1 -0
  696. package/dist/next-node/plugins/install.js +37 -0
  697. package/dist/next-node/plugins/install.js.map +1 -0
  698. package/dist/next-node/plugins/plugins.d.ts +135 -0
  699. package/dist/next-node/plugins/plugins.d.ts.map +1 -0
  700. package/dist/next-node/plugins/plugins.js +206 -0
  701. package/dist/next-node/plugins/plugins.js.map +1 -0
  702. package/dist/next-node/plugins/runtime.d.ts +41 -0
  703. package/dist/next-node/plugins/runtime.d.ts.map +1 -0
  704. package/dist/next-node/plugins/runtime.js +136 -0
  705. package/dist/next-node/plugins/runtime.js.map +1 -0
  706. package/dist/next-node/plugins/stack.d.ts +16 -0
  707. package/dist/next-node/plugins/stack.d.ts.map +1 -0
  708. package/dist/next-node/plugins/stack.js +61 -0
  709. package/dist/next-node/plugins/stack.js.map +1 -0
  710. package/dist/next-node/plugins/watcher.d.ts +58 -0
  711. package/dist/next-node/plugins/watcher.d.ts.map +1 -0
  712. package/dist/next-node/plugins/watcher.js +281 -0
  713. package/dist/next-node/plugins/watcher.js.map +1 -0
  714. package/dist/next-node/workers/control.d.ts +83 -0
  715. package/dist/next-node/workers/control.d.ts.map +1 -0
  716. package/dist/next-node/workers/control.js +77 -0
  717. package/dist/next-node/workers/control.js.map +1 -0
  718. package/dist/next-node/workers/index.d.ts +5 -0
  719. package/dist/next-node/workers/index.d.ts.map +1 -0
  720. package/dist/next-node/workers/index.js +7 -0
  721. package/dist/next-node/workers/index.js.map +1 -0
  722. package/dist/next-node/workers/lock.d.ts +21 -0
  723. package/dist/next-node/workers/lock.d.ts.map +1 -0
  724. package/dist/next-node/workers/lock.js +137 -0
  725. package/dist/next-node/workers/lock.js.map +1 -0
  726. package/dist/next-node/workers/main.d.ts +46 -0
  727. package/dist/next-node/workers/main.d.ts.map +1 -0
  728. package/dist/next-node/workers/main.js +230 -0
  729. package/dist/next-node/workers/main.js.map +1 -0
  730. package/dist/next-node/workers/process.d.ts +42 -0
  731. package/dist/next-node/workers/process.d.ts.map +1 -0
  732. package/dist/next-node/workers/process.js +125 -0
  733. package/dist/next-node/workers/process.js.map +1 -0
  734. package/dist/next-node/workers/workers.d.ts +80 -0
  735. package/dist/next-node/workers/workers.d.ts.map +1 -0
  736. package/dist/next-node/workers/workers.js +572 -0
  737. package/dist/next-node/workers/workers.js.map +1 -0
  738. package/dist/object.d.ts +4 -4
  739. package/dist/object.d.ts.map +1 -1
  740. package/dist/object.js +3 -4
  741. package/dist/object.js.map +1 -1
  742. package/dist/output.d.ts +1 -1
  743. package/dist/output.d.ts.map +1 -1
  744. package/dist/output.js +4 -2
  745. package/dist/output.js.map +1 -1
  746. package/dist/remote.d.ts.map +1 -1
  747. package/dist/remote.js +2 -2
  748. package/dist/remote.js.map +1 -1
  749. package/dist/schema.d.ts +8 -4
  750. package/dist/schema.d.ts.map +1 -1
  751. package/dist/schema.js +180 -5
  752. package/dist/schema.js.map +1 -1
  753. package/dist/sqlite/cloudflare.d.ts +2 -0
  754. package/dist/sqlite/cloudflare.d.ts.map +1 -1
  755. package/dist/sqlite/cloudflare.js +10 -0
  756. package/dist/sqlite/cloudflare.js.map +1 -1
  757. package/dist/sqlite/database.d.ts +5 -2
  758. package/dist/sqlite/database.d.ts.map +1 -1
  759. package/dist/sqlite/database.js.map +1 -1
  760. package/dist/sqlite/node.d.ts +4 -1
  761. package/dist/sqlite/node.d.ts.map +1 -1
  762. package/dist/sqlite/node.js +22 -5
  763. package/dist/sqlite/node.js.map +1 -1
  764. package/dist/watch.d.ts +194 -0
  765. package/dist/watch.d.ts.map +1 -0
  766. package/dist/watch.js +383 -0
  767. package/dist/watch.js.map +1 -0
  768. package/dist/wire.d.ts +174 -193
  769. package/dist/wire.d.ts.map +1 -1
  770. package/dist/wire.js +81 -80
  771. package/dist/wire.js.map +1 -1
  772. package/docs/guide.md +15 -15
  773. package/docs/next/benchmarks.md +959 -0
  774. package/docs/next/decisions.md +2957 -0
  775. package/docs/next/dependencies/book.md +1671 -0
  776. package/docs/next/dependencies/index.html +2641 -0
  777. package/docs/next/dependencies/model.md +330 -0
  778. package/docs/next/design.md +2554 -0
  779. package/docs/next/durable-observers/book.md +432 -0
  780. package/docs/next/durable-observers/index.html +517 -0
  781. package/docs/next/flow-control/book.md +333 -0
  782. package/docs/next/flow-control/fold/index.html +265 -0
  783. package/docs/next/flow-control/index.html +548 -0
  784. package/docs/next/flow-control/window/index.html +228 -0
  785. package/docs/next/guide-plugins-hosts/book.md +607 -0
  786. package/docs/next/guide-plugins-hosts/index.html +652 -0
  787. package/docs/next/http-workers/book.md +378 -0
  788. package/docs/next/http-workers/index.html +515 -0
  789. package/docs/next/layer-1.md +311 -0
  790. package/docs/next/layer-2.md +216 -0
  791. package/docs/next/plugin-model/book.md +186 -0
  792. package/docs/next/plugin-model/index.html +310 -0
  793. package/docs/next/plugin-primer/book.md +273 -0
  794. package/docs/next/plugin-primer/index.html +430 -0
  795. package/docs/next/slice-1.md +236 -0
  796. package/docs/next/slice-10.md +285 -0
  797. package/docs/next/slice-11.md +93 -0
  798. package/docs/next/slice-2.md +174 -0
  799. package/docs/next/slice-3a.md +296 -0
  800. package/docs/next/slice-3b.md +197 -0
  801. package/docs/next/slice-4.md +146 -0
  802. package/docs/next/slice-4a.md +418 -0
  803. package/docs/next/slice-4b.md +208 -0
  804. package/docs/next/slice-5.md +281 -0
  805. package/docs/next/slice-6a.md +676 -0
  806. package/docs/next/slice-6b.md +332 -0
  807. package/docs/next/slice-7a.md +130 -0
  808. package/docs/next/slice-7b/book.md +608 -0
  809. package/docs/next/slice-7b/index.html +842 -0
  810. package/docs/next/slice-7b.md +255 -0
  811. package/docs/next/slice-7c.md +165 -0
  812. package/docs/next/slice-8.md +194 -0
  813. package/docs/next/slices.md +230 -0
  814. package/docs/next/store/book.md +665 -0
  815. package/docs/next/store/index.html +861 -0
  816. package/docs/next/store/walkthrough.md +193 -0
  817. package/docs/spec.md +9 -9
  818. package/docs/tutorial.md +26 -25
  819. package/package.json +22 -6
  820. package/src/delta/README.md +69 -0
@@ -0,0 +1,652 @@
1
+ <!doctype html>
2
+ <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
3
+ <title>Hosts and Plugins: a tutorial for Chord v2</title>
4
+ <style>
5
+
6
+ :root{--paper:#fbf8f2;--ink:#2a2723;--muted:#7b7468;--rule:#e3dbcc;--accent:#b4472f;--blue:#2e6a8a;--sand:#c2b18c;--soft:#f4eee2}
7
+ *{box-sizing:border-box}
8
+ html{background:#efe9dd}
9
+ body{margin:0;color:var(--ink);font:19px/1.68 'Iowan Old Style','Palatino Linotype',Palatino,'Book Antiqua',Georgia,serif;
10
+ -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
11
+ .book{max-width:860px;margin:0 auto;background:var(--paper);box-shadow:0 0 0 1px #e1d9c8,0 30px 80px -40px rgba(60,40,10,.35);padding:0 0 4rem}
12
+ .inner{padding:0 90px}
13
+ h1,h2,h3{font-weight:400;line-height:1.15}
14
+ h2{font-size:2.1rem;margin:.2em 0 .3em;letter-spacing:-.01em}
15
+ h3{font-size:1.05rem;text-transform:uppercase;letter-spacing:.14em;margin:2.4em 0 .6em;color:var(--ink);font-weight:600;
16
+ font-family:'Avenir Next','Helvetica Neue',sans-serif}
17
+ p{margin:0 0 1.05em;hyphens:auto;text-align:left}
18
+ code{font:.8em/1 'SF Mono',Menlo,Consolas,monospace;background:#f1ebde;padding:.1em .35em;border-radius:3px}
19
+ pre{font:.74rem/1.55 'SF Mono',Menlo,Consolas,monospace;background:#f4eee2;border-left:3px solid var(--sand);padding:1rem 1.2rem;margin:1.4rem 0 1.8rem;
20
+ overflow-x:auto;border-radius:0 4px 4px 0;white-space:pre;tab-size:2}
21
+ pre code{background:none;padding:0;font-size:1em}
22
+ em{font-style:italic}
23
+ a{color:var(--blue)}
24
+ .cover{min-height:92vh;display:flex;flex-direction:column;justify-content:center;padding:90px;background:
25
+ radial-gradient(circle at 85% 15%,rgba(180,71,47,.13),transparent 40%),radial-gradient(circle at 10% 90%,rgba(46,106,138,.12),transparent 45%),var(--paper);
26
+ border-bottom:1px solid var(--rule)}
27
+ .kicker{font:600 .78rem 'Avenir Next','Helvetica Neue',sans-serif;letter-spacing:.22em;text-transform:uppercase;color:var(--accent)}
28
+ .cover h1{font-size:5.2rem;line-height:.98;margin:.35em 0 .25em;letter-spacing:-.025em}
29
+ .subtitle{font-size:1.45rem;font-style:italic;color:#4a453e;max-width:30em;text-align:left}
30
+ .cover-stats,.stats{display:flex;flex-wrap:wrap;gap:1.2rem 2.4rem;margin:2.2rem 0}
31
+ .stats{margin:1.6rem 0 1.8rem;padding:1.1rem 0;border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
32
+ .stat b{display:block;font-size:2.1rem;font-weight:400;line-height:1.1;font-variant-numeric:lining-nums}
33
+ .stat span{font:.78rem/1.3 'Avenir Next','Helvetica Neue',sans-serif;color:var(--muted);letter-spacing:.03em;display:block;max-width:14em}
34
+ .cover-note{font-size:.9rem;color:var(--muted);max-width:34em;text-align:left;margin-top:2rem}
35
+ .toc{padding:4rem 0 2rem}
36
+ .toc ol{list-style:none;padding:0;margin:1rem 0;columns:2;column-gap:3rem}
37
+ .toc li{padding:.3rem 0;border-bottom:1px dotted var(--rule);break-inside:avoid}
38
+ .toc a{color:var(--ink);text-decoration:none}
39
+ .toc a:hover{color:var(--accent)}
40
+ .preface{padding-top:2rem}
41
+ .findings{padding-left:1.4em}
42
+ .findings li{margin:.55em 0;padding-left:.3em}
43
+ .findings li::marker{color:var(--accent);font-weight:600}
44
+ .chapter{padding-top:4.5rem;margin-top:3rem;border-top:1px solid var(--rule)}
45
+ .opener{text-align:center;margin-bottom:2.6rem}
46
+ .numeral{font-size:4.2rem;color:var(--accent);line-height:1;font-variant:small-caps;letter-spacing:.05em}
47
+ .opener h2{font-size:2.5rem;margin:.25em 0}
48
+ .lede{font-style:italic;color:#5a544a;font-size:1.12rem;max-width:30em;margin:0 auto;text-align:center}
49
+ .dropcap::first-letter{float:left;font-size:4.1em;line-height:.82;padding:.06em .09em 0 0;color:var(--accent)}
50
+ .fig{margin:2rem 0 2.2rem}
51
+ .fig.wide{margin-left:-50px;margin-right:-50px}
52
+ .fig svg{display:block;margin:0 auto}
53
+ figcaption{font:.8rem/1.45 'Avenir Next','Helvetica Neue',sans-serif;color:var(--muted);margin-top:.7rem;padding-left:.8rem;border-left:2px solid var(--rule)}
54
+ .fignum{color:var(--ink);font-weight:600}
55
+ .note{font:.86rem/1.55 'Avenir Next','Helvetica Neue',sans-serif;color:#5b5549;background:#f4eee2;border-left:3px solid var(--sand);
56
+ padding:.9rem 1.1rem;margin:1.8rem 0;border-radius:0 4px 4px 0}
57
+ .note.review{border-left-color:var(--accent)}
58
+ .note b.tag{font-weight:600;letter-spacing:.12em;text-transform:uppercase;font-size:.72rem;color:var(--accent);display:block;margin-bottom:.3rem}
59
+ .note code{font-size:.85em}
60
+ table{width:100%;border-collapse:collapse;margin:1.4rem 0 1.8rem;font:.8rem/1.4 'Avenir Next','Helvetica Neue',sans-serif}
61
+ th{text-align:left;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;font-size:.68rem;border-bottom:1.5px solid var(--ink);padding:.45rem .5rem}
62
+ td{padding:.42rem .5rem;border-bottom:1px solid var(--rule);vertical-align:top}
63
+ td code{font-size:.92em}
64
+ table.num td:not(:first-child),table.num th:not(:first-child){text-align:right}
65
+ .epilogue p{font-size:1.04em}
66
+ .appendix{font-size:.92em}
67
+ .appendix ul,.chapter ul{padding-left:1.2em}
68
+ .appendix li,.chapter li{margin:.4em 0}
69
+ .colophon{text-align:center;font:.78rem 'Avenir Next','Helvetica Neue',sans-serif;color:var(--muted);margin-top:4rem;letter-spacing:.05em}
70
+ @media (max-width:760px){.inner{padding:0 22px}.cover{padding:40px 22px}.cover h1{font-size:3.2rem}.fig.wide{margin-left:0;margin-right:0}
71
+ .toc ol{columns:1}p{text-align:left}body{font-size:17px}}
72
+ @media print{html{background:#fff}.book{box-shadow:none}.chapter{break-before:page}.fig{break-inside:avoid}}
73
+ .transcript p b{font:600 .78rem 'Avenir Next','Helvetica Neue',sans-serif;letter-spacing:.08em;text-transform:uppercase;color:var(--accent);margin-right:.3em}
74
+ pre .tk-c{color:#8d8576;font-style:italic}pre .tk-s{color:#5f7a3d}pre .tk-n{color:#a0662a}pre .tk-k{color:#b4472f}pre .tk-t{color:#2e6a8a}pre .tk-f{color:#7a3f6a}
75
+ h4{font:600 .82rem 'Avenir Next','Helvetica Neue',sans-serif;letter-spacing:.06em;margin:1.8em 0 .5em;color:var(--muted)}
76
+ .inner ul,.inner ol:not(.findings){padding-left:1.2em}
77
+ .inner li{margin:.35em 0}
78
+ blockquote{margin:1.4rem 0;padding:.2rem 0 .2rem 1.2rem;border-left:3px solid var(--rule);color:#5a544a;font-style:italic}
79
+ .fig svg text{dominant-baseline:auto}
80
+ .fig .replay{font:600 .7rem 'Avenir Next','Helvetica Neue',sans-serif;letter-spacing:.1em;text-transform:uppercase;color:var(--accent);
81
+ background:none;border:1px solid var(--rule);border-radius:3px;padding:.2rem .55rem;margin:0 0 0 1rem;cursor:pointer;float:right}
82
+ .fig .replay:hover{border-color:var(--accent)}
83
+ .anim.armed .step{opacity:0}
84
+ .anim.armed.play .step{animation:stepIn .45s ease-out both;animation-delay:calc(var(--i) * var(--pace, .45s))}
85
+ .anim.armed.play .step.edge{animation-name:edgeIn}
86
+ @keyframes stepIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
87
+ @keyframes edgeIn{from{opacity:0}to{opacity:1}}
88
+ .steps{margin:2rem 0 2.2rem;border:1px solid var(--rule);border-radius:6px;background:#fffdf8}
89
+ .steps-head{display:flex;align-items:center;gap:.8rem;padding:.6rem 1rem;border-bottom:1px solid var(--rule);
90
+ font:600 .72rem 'Avenir Next','Helvetica Neue',sans-serif;letter-spacing:.12em;text-transform:uppercase;color:var(--accent)}
91
+ .steps-head .title{flex:1}
92
+ .steps-head .count{color:var(--muted);letter-spacing:.06em}
93
+ .steps-head button{font:600 .72rem 'Avenir Next','Helvetica Neue',sans-serif;color:var(--ink);background:var(--soft);border:1px solid var(--rule);
94
+ border-radius:3px;padding:.25rem .65rem;cursor:pointer}
95
+ .steps-head button:disabled{opacity:.35;cursor:default}
96
+ .step-panel{padding:1rem 1.2rem .4rem}
97
+ .step-panel>h4:first-child{margin-top:.2rem;color:var(--ink)}
98
+ .steps.js .step-panel{display:none}
99
+ .steps.js .step-panel.on{display:block}
100
+ .steps:not(.js) .steps-head button,.steps:not(.js) .steps-head .count{display:none}
101
+ .steps:not(.js) .step-panel+.step-panel{border-top:1px dashed var(--rule)}
102
+ .fig figcaption{display:flow-root}
103
+ .fig svg{max-width:100%;height:auto}
104
+ table{max-width:100%}
105
+ @media (max-width:760px){.inner{padding:0 20px}.cover{padding:48px 22px}.cover h1{font-size:3.2rem}.fig.wide{margin-left:0;margin-right:0}table{display:block;overflow-x:auto}.toc ol{columns:1}}
106
+ </style>
107
+
108
+
109
+ </head>
110
+ <body><div class="book">
111
+ <section class="cover">
112
+ <div class="kicker">A guide · Chord v2 · 2026-10-31</div>
113
+ <h1>Hosts<br>and Plugins</h1>
114
+ <p class="subtitle">Build a small notes app step by step, from one host to plugins on a server and on workers, edited while it runs</p>
115
+ <div class="cover-stats"><div class="stat"><b>3</b><span>kinds of host in an app: server, worker, client</span></div><div class="stat"><b>1</b><span>file per host kind in a plugin</span></div><div class="stat"><b>0</b><span>restarts to apply a plugin edit</span></div><div class="stat"><b>1</b><span>rule: plugins talk only through object types and registries</span></div></div>
116
+ <div class="cover-note"><p>A tutorial for people building apps on Chord v2, written by the redesign session from <code>design.md</code>, <code>slice-7c.md</code>,
117
+ <code>slice-10.md</code>, the decision log and the code in <code>packages/chord/src/next</code> and <code>src/next-node</code>. API names are the
118
+ current ones; where slice 10&#39;s fix round or the app kit (<code>chord/next/app</code>, being designed) will change what app code
119
+ writes, a note says so.</p>
120
+ </div>
121
+ </section><div class="inner">
122
+ <nav class="toc"><h2>Contents</h2><ol>
123
+ <li><a href="#before-we-begin">Before we begin</a></li>
124
+ <li><a href="#host">I. One Host</a></li>
125
+ <li><a href="#parts">II. An Object&#39;s Parts</a></li>
126
+ <li><a href="#hosts">III. Several Hosts</a></li>
127
+ <li><a href="#clients">IV. Client Hosts</a></li>
128
+ <li><a href="#plugins">V. Plugins</a></li>
129
+ <li><a href="#loading">VI. Loading Plugins</a></li>
130
+ <li><a href="#together">VII. Plugins Using Plugins</a></li>
131
+ <li><a href="#reload">VIII. Changing a Plugin</a></li>
132
+ <li><a href="#base">IX. Base Code and Plugins</a></li>
133
+ <li><a href="#reference">Appendix A: Reference</a></li>
134
+ </ol></nav>
135
+
136
+ <section class="preface" id="before-we-begin">
137
+ <h2>Before we begin</h2>
138
+ <p class="dropcap">You want to build a notes app. You type a note in a browser tab, and every other tab sees it at once. Each project
139
+ gets its own notes in its own process, so a project that misbehaves cannot take the others down. And you, or an agent
140
+ you work with, add features while the app runs: a search, an export button, a word count, without restarting
141
+ anything.</p>
142
+ <p>Chord gives you three things for that. <strong>Hosts</strong>: the processes of your app (the server, a worker per project, the
143
+ browser tabs), connected to each other. <strong>Objects</strong>: the state and methods your app is made of, living on one host and
144
+ used from any other. <strong>Plugins</strong>: directories of code that declare objects for each kind of host, loaded and
145
+ reloaded while the app runs.</p>
146
+ <p>This book builds the app in that order. Each chapter adds one concept and shows complete code.</p>
147
+ <h3 id="seven-things-to-know">Seven things to know</h3>
148
+ <ol class="findings">
149
+ <li><strong>A host is one participant.</strong> The server, each worker, each browser tab and each terminal UI is a host; hosts
150
+ connect over links. Tabs and terminal UIs are clients: no address, they connect to the server and ask.</li>
151
+ <li><strong>An object has a type, and a type is a contract.</strong> The contract names the object&#39;s state and methods; any host can
152
+ ask for an object by type and params, and Chord finds where it lives.</li>
153
+ <li><strong>A facet declares, an object acts.</strong> A facet is a plugin&#39;s code for one host kind: it says which object types this
154
+ host serves. The objects hold the state and do the work.</li>
155
+ <li><strong>A plugin is a directory.</strong> A <code>package.json</code> with the plugin&#39;s name, and one file per host kind: <code>server.ts</code>,
156
+ <code>worker.ts</code>, <code>web.tsx</code>.</li>
157
+ <li><strong>The server builds, every host evaluates.</strong> The plugins component builds each facet into a small script; the
158
+ server, workers and tabs load the scripts for their kind.</li>
159
+ <li><strong>Plugins meet through types and registries.</strong> One plugin uses another&#39;s objects through its contract, or
160
+ contributes to a registry another defines. Nothing else crosses between plugins.</li>
161
+ <li><strong>An edit is a rollout.</strong> Change a file, build, roll out: the server, then every worker, swap the plugin&#39;s objects in
162
+ place; a broken edit keeps the old code running and reports why.</li>
163
+ </ol>
164
+ <figure class="fig wide anim"><svg viewBox="0 0 720 396" width="100%" role="img" aria-label="How it all fits: plugins on disk are built once on the server; each host evaluates the facets of its kind; tabs and the TUI are clients that reach workers' objects through the server." xmlns="http://www.w3.org/2000/svg" style="font-family:'Avenir Next','Helvetica Neue',Helvetica,Arial,sans-serif;max-width:760px"><defs><marker id="f1m" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L8,4 L0,8 z" fill="#7b7468"/></marker><marker id="f1a" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L8,4 L0,8 z" fill="#b4472f"/></marker><marker id="f1b" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L8,4 L0,8 z" fill="#2e6a8a"/></marker></defs><text x="16" y="22" font-size="10" fill="#7b7468" text-anchor="start" font-weight="600" letter-spacing="2">ON DISK</text><text x="16" y="155" font-size="10" fill="#b4472f" text-anchor="start" font-weight="600" letter-spacing="2">SERVER PROCESS</text><text x="16" y="288" font-size="10" fill="#7b7468" text-anchor="start" font-weight="600" letter-spacing="2">CLIENTS AND WORKERS</text><g class="step" style="--i:1"><rect x="137" y="36" width="210" height="55" rx="4" fill="#efe9dd" stroke="#c9bfae"/><text x="242" y="54.5" font-size="11" fill="#2a2723" text-anchor="middle">plugins/notes/</text><text x="242" y="68.5" font-size="9.5" fill="#7b7468" text-anchor="middle" font-family="Menlo,monospace">server.ts`, `worker.ts`,</text><text x="242" y="81" font-size="9.5" fill="#7b7468" text-anchor="middle" font-family="Menlo,monospace">`web.tsx`, `tui.ts`, `contract.ts</text></g><g class="step" style="--i:4"><rect x="373" y="36" width="210" height="55" rx="4" fill="#efe9dd" stroke="#c9bfae"/><text x="478" y="60.8" font-size="11" fill="#2a2723" text-anchor="middle">src/ (base code)</text><text x="478" y="74.8" font-size="9.5" fill="#7b7468" text-anchor="middle">`@app/core`: host kinds, principals</text></g><g class="step" style="--i:3"><rect x="137" y="169" width="210" height="55" rx="4" fill="#fff" stroke="#b4472f" stroke-width="1.5"/><text x="242" y="187.5" font-size="11" fill="#2a2723" text-anchor="middle">plugins component</text><text x="242" y="201.5" font-size="9.5" fill="#7b7468" text-anchor="middle">discover, build every facet, watch,</text><text x="242" y="214" font-size="9.5" fill="#7b7468" text-anchor="middle">roll out</text></g><g class="step" style="--i:7"><rect x="373" y="169" width="210" height="55" rx="4" fill="#fff" stroke="#c9bfae"/><text x="478" y="187.5" font-size="11" fill="#2a2723" text-anchor="middle">server host</text><text x="478" y="201.5" font-size="9.5" fill="#7b7468" text-anchor="middle">server facets; routes Project →</text><text x="478" y="214" font-size="9.5" fill="#7b7468" text-anchor="middle">workers</text></g><g class="step" style="--i:9"><rect x="137" y="302" width="210" height="55" rx="4" fill="#fff" stroke="#2e6a8a" stroke-width="1.5"/><text x="242" y="320.5" font-size="11" fill="#2a2723" text-anchor="middle">client: tab or TUI</text><text x="242" y="334.5" font-size="9.5" fill="#7b7468" text-anchor="middle">web or tui facets, local UI objects;</text><text x="242" y="347" font-size="9.5" fill="#7b7468" text-anchor="middle">holds `Notes { p1 }`</text></g><g class="step" style="--i:12"><rect x="373" y="302" width="210" height="55" rx="4" fill="#fff" stroke="#c9bfae"/><text x="478" y="326.8" font-size="11" fill="#2a2723" text-anchor="middle">worker p1</text><text x="478" y="340.8" font-size="9.5" fill="#7b7468" text-anchor="middle">worker facets; serves `Notes { p1 }`</text></g><g class="step edge" style="--i:2"><path d="M242 91 L242 167" fill="none" stroke="#7b7468" marker-end="url(#f1m)"/><rect x="246" y="123" width="65.9" height="13" fill="#fbf8f2" opacity=".92"/><text x="250" y="133" font-size="9.5" fill="#7b7468" text-anchor="start">read, build</text></g><g class="step edge" style="--i:5"><path d="M478 91 L242 167" fill="none" stroke="#7b7468" marker-end="url(#f1m)"/><rect x="364" y="123" width="76.5" height="13" fill="#fbf8f2" opacity=".92"/><text x="368" y="133" font-size="9.5" fill="#7b7468" text-anchor="start">host packages</text></g><g class="step edge" style="--i:6"><path d="M347 196.5 L371 196.5" fill="none" stroke="#7b7468" marker-end="url(#f1m)"/><rect x="319.1" y="179.5" width="81.8" height="13" fill="#fbf8f2" opacity=".92"/><text x="360" y="189.5" font-size="9.5" fill="#7b7468" text-anchor="middle">server scripts</text></g><g class="step edge" style="--i:8"><path d="M242 224 L242 300" fill="none" stroke="#7b7468" marker-end="url(#f1m)"/><rect x="246" y="256" width="102.8" height="13" fill="#fbf8f2" opacity=".92"/><text x="250" y="266" font-size="9.5" fill="#7b7468" text-anchor="start">web or tui scripts</text></g><g class="step edge" style="--i:10"><path d="M242 302 L478 226" fill="none" stroke="#7b7468" marker-end="url(#f1m)"/><rect x="364" y="258" width="97.6" height="13" fill="#fbf8f2" opacity=".92"/><text x="368" y="268" font-size="9.5" fill="#7b7468" text-anchor="start">hold Notes { p1 }</text></g><g class="step edge" style="--i:11"><path d="M478 224 L478 300" fill="none" stroke="#7b7468" marker-end="url(#f1m)"/><rect x="482" y="256" width="160.8" height="13" fill="#fbf8f2" opacity=".92"/><text x="486" y="266" font-size="9.5" fill="#7b7468" text-anchor="start">start (worker scripts), relay</text></g><text x="16" y="381" font-size="10.5" fill="#7b7468" text-anchor="start">Each host loads only its own kind's facets. Plugins meet only through object types and registries.</text></svg><figcaption><button class="replay" type="button">Replay</button><span class="fignum">Figure 1.</span> How it all fits: plugins on disk are built once on the server; each host evaluates the facets of its kind; tabs and the TUI are clients that reach workers&#39; objects through the server.</figcaption></figure>
165
+ <h3 id="words-used-throughout">Words used throughout</h3>
166
+ <p>A <strong>host</strong> is one participant of the app, made with <code>createHost</code>. A <strong>host kind</strong> (<code>Server</code>, <code>Session</code>) describes
167
+ addressable hosts; an <strong>address</strong> (<code>Session({ id: &quot;p1&quot; })</code>) names one. An <strong>object type</strong> is a contract: <code>local</code> (used
168
+ on its own host only) or <code>remote</code> (used from any host). An <strong>object</strong> is one instance of a type, per params. A
169
+ <strong>facet</strong> is a plugin&#39;s declarations for one host kind. A <strong>plugin</strong> is a directory with a <code>package.json</code>. A
170
+ <strong>reference</strong> is what you get when you ask for an object (<code>host.get</code>, <code>self.get</code>, <code>ctx.get</code>). A <strong>document</strong> is data an object
171
+ stores, changed in <strong>transactions</strong>; a <strong>table</strong> holds many records with queries, in the host&#39;s <strong>store</strong>; a <strong>derive</strong> is a value computed from others; a <strong>native</strong> is an outside
172
+ resource an object opens and closes. A <strong>registry</strong> is an
173
+ extension point: one plugin defines it, others contribute. A <strong>rollout</strong> applies a build to the hosts in order.</p>
174
+ </section>
175
+
176
+ <section class="chapter" id="host"><header class="opener"><div class="numeral">I</div><h2>One Host</h2><p class="lede">The smallest app: one process, one object type, one call.</p></header>
177
+ <p class="dropcap">Start without plugins. One host, one object that keeps notes:</p>
178
+ <pre><code><span class="tk-k">import</span> { createHost, defineFacet, defineState, local, method, obj, arr, str } <span class="tk-k">from</span> <span class="tk-s">"@earendil-works/chord/next"</span>;
179
+
180
+ <span class="tk-k">const</span> <span class="tk-t">NoteList</span> = <span class="tk-f">obj</span>({ items: <span class="tk-f">arr</span>(<span class="tk-f">str</span>()) }); <span class="tk-c">// one schema, used by the contract and the document</span>
181
+
182
+ <span class="tk-c">// the contract: what a Notes object offers</span>
183
+ <span class="tk-k">const</span> <span class="tk-t">Notes</span> = <span class="tk-f">local</span>(<span class="tk-s">"notes.store"</span>, {
184
+ version: <span class="tk-n">1</span>,
185
+ params: {}, <span class="tk-c">// one object per host: no params</span>
186
+ members: {
187
+ list: <span class="tk-t">NoteList</span>, <span class="tk-c">// state anyone can read and watch</span>
188
+ add: <span class="tk-f">method</span>(<span class="tk-f">obj</span>({ text: <span class="tk-f">str</span>() })), <span class="tk-c">// a method: arguments checked by Chord</span>
189
+ },
190
+ });
191
+
192
+ <span class="tk-c">// the document the object stores (its own version: storage can change without changing the contract)</span>
193
+ <span class="tk-k">const</span> <span class="tk-t">NotesDoc</span> = <span class="tk-f">defineState</span>(<span class="tk-s">"notes"</span>, { schema: <span class="tk-t">NoteList</span>, version: <span class="tk-n">1</span>, initial: () =&gt; ({ items: [] }) });
194
+
195
+ <span class="tk-c">// the facet: which types this host serves, and how to make each object</span>
196
+ <span class="tk-k">const</span> facet = <span class="tk-f">defineFacet</span>((host) =&gt; {
197
+ host.<span class="tk-f">serve</span>(<span class="tk-t">Notes</span>, (_params, self) =&gt; {
198
+ <span class="tk-k">const</span> doc = self.<span class="tk-f">state</span>(<span class="tk-t">NotesDoc</span>);
199
+ <span class="tk-k">return</span> {
200
+ list: doc,
201
+ add: <span class="tk-k">async</span> ({ text }, ctx) =&gt; self.<span class="tk-f">tx</span>(<span class="tk-k">async</span> (tx) =&gt; { (<span class="tk-k">await</span> tx.<span class="tk-f">draft</span>(doc)).items.<span class="tk-f">push</span>(text); }, ctx),
202
+ };
203
+ });
204
+ });
205
+
206
+ <span class="tk-k">const</span> server = <span class="tk-f">createHost</span>({ onError: console.error });
207
+ <span class="tk-k">await</span> server.<span class="tk-f">load</span>([{ name: <span class="tk-s">"@app/notes"</span>, facet }], ctx);
208
+ <span class="tk-k">const</span> notes = <span class="tk-k">await</span> server.<span class="tk-f">get</span>(<span class="tk-t">Notes</span>, {}, ctx); <span class="tk-c">// a reference: live, with its state</span>
209
+ <span class="tk-k">await</span> notes.<span class="tk-f">add</span>({ text: <span class="tk-s">"buy milk"</span> }, ctx);
210
+ console.<span class="tk-f">log</span>(notes.list.value); <span class="tk-c">// { items: ["buy milk"] }</span></code></pre>
211
+ <p>Four things happened. The <strong>contract</strong> <code>Notes</code> says what the object offers; the <strong>document</strong> says what it stores.
212
+ Here they have the same shape, so one schema serves both; they are separate because they change separately (an
213
+ object may offer a computed value or a shortened view instead of what it stores, and storage can change its shape
214
+ without users noticing).
215
+ The <strong>facet</strong> says this host serves
216
+ <code>Notes</code>, with a <strong>factory</strong> that declares the object&#39;s parts: a document, and a method writing it in a transaction.
217
+ <code>load</code> publishes the facet. <code>get</code> returns a <strong>reference</strong> once the object is live; its members are the contract&#39;s.</p>
218
+ <p>The factory only declares: it is synchronous and opens nothing. Chord activates the object (loads its documents, opens
219
+ what it asked to open) and then serves calls. That is why the same factory can run again when the code changes.</p>
220
+ </section>
221
+
222
+ <section class="chapter" id="parts"><header class="opener"><div class="numeral">II</div><h2>An Object&#39;s Parts</h2><p class="lede">Documents, tables, transactions, computed values, watching, and outside resources: the vocabulary of every factory.</p></header>
223
+ <p class="dropcap">A factory builds an object from a handful of parts, each declared with one call on <code>self</code>. The notes object grows to
224
+ show all of them.</p>
225
+ <p><strong>Documents</strong> hold the object&#39;s data: <code>self.state(NotesDoc)</code> gives a handle whose <code>.value</code> is the current data. Data
226
+ changes only in a <strong>transaction</strong>: <code>self.tx(fn, ctx)</code> runs <code>fn</code> with <code>tx</code>, and <code>await tx.draft(handle)</code> gives a
227
+ mutable copy of the document&#39;s data; whatever you change on it is committed at once when <code>fn</code> returns, or not at all
228
+ if it throws.</p>
229
+ <pre><code>add: <span class="tk-k">async</span> ({ text }, ctx) =&gt; self.<span class="tk-f">tx</span>(<span class="tk-k">async</span> (tx) =&gt; {
230
+ <span class="tk-k">const</span> draft = <span class="tk-k">await</span> tx.<span class="tk-f">draft</span>(doc); <span class="tk-c">// the document's data, writable inside this transaction only</span>
231
+ draft.items.<span class="tk-f">push</span>(text); <span class="tk-c">// recorded as a change, committed when the function returns</span>
232
+ }, ctx),</code></pre>
233
+ <p>Documents live in memory unless they are <strong>persisted</strong>: <code>defineState(..., { persist: true, checkpointWhen })</code> keeps
234
+ one in the host&#39;s <strong>store</strong> (a SQLite file the app opens and gives to <code>createHost({ store })</code>), loaded when the
235
+ object activates. For many records with queries, an object declares a <strong>table</strong>:</p>
236
+ <pre><code><span class="tk-k">const</span> <span class="tk-t">NoteRows</span> = <span class="tk-f">defineTable</span>(<span class="tk-s">"notes"</span>, {
237
+ version: <span class="tk-n">1</span>,
238
+ columns: { id: <span class="tk-f">str</span>(), text: <span class="tk-f">str</span>(), at: <span class="tk-f">int</span>() },
239
+ key: [<span class="tk-s">"id"</span>],
240
+ indexes: { by_time: [<span class="tk-s">"at"</span>] },
241
+ });
242
+
243
+ host.<span class="tk-f">serve</span>(<span class="tk-t">NoteStore</span>, (_params, self) =&gt; { <span class="tk-c">// a local type with empty params: it may persist</span>
244
+ <span class="tk-k">const</span> rows = self.<span class="tk-f">table</span>(<span class="tk-t">NoteRows</span>); <span class="tk-c">// created (or migrated) when the object activates</span>
245
+ <span class="tk-k">const</span> recent = <span class="tk-f">query</span>(<span class="tk-t">NoteRows</span>).<span class="tk-f">orderBy</span>((n) =&gt; n.at, <span class="tk-s">"desc"</span>);
246
+ <span class="tk-k">return</span> {
247
+ add: <span class="tk-k">async</span> ({ text }, ctx) =&gt; self.<span class="tk-f">tx</span>(<span class="tk-k">async</span> (tx) =&gt; tx.<span class="tk-f">put</span>(rows, { id: <span class="tk-f">uuid</span>(), text, at: <span class="tk-t">Date</span>.<span class="tk-f">now</span>() }), ctx),
248
+ page: <span class="tk-k">async</span> ({ after }, ctx) =&gt; rows.<span class="tk-f">page</span>(recent, <span class="tk-n">50</span>, ctx, { after }), <span class="tk-c">// 50 at a time, with a cursor</span>
249
+ };
250
+ });</code></pre>
251
+ <p>Persisted data lives only in <code>local</code> objects with empty params (one per host and type), so its address never depends
252
+ on who asked or with which params; an object with params (a view per project) reads from such a store. Writes go
253
+ through the same transactions as documents: a note row and a document can change in one commit.</p>
254
+ <p>A <strong>derive</strong> is a value computed from other values, recomputed whenever they change. It is how an object offers
255
+ something it does not store:</p>
256
+ <pre><code><span class="tk-k">const</span> count = self.<span class="tk-f">derive</span>([doc], ([notes]) =&gt; notes.items.length); <span class="tk-c">// 0, 1, 2, … as notes are added</span>
257
+ <span class="tk-k">return</span> { list: doc, count, add }; <span class="tk-c">// `count` can be a member like `list`</span></code></pre>
258
+ <p><strong>Watching</strong> is how anyone follows a value as it changes: a document handle, a derive, a reference&#39;s member. <code>watch</code>
259
+ gives the current value, then one call per change:</p>
260
+ <pre><code><span class="tk-k">const</span> watch = <span class="tk-k">await</span> notes.count.<span class="tk-f">watch</span>(ctx);
261
+ watch.<span class="tk-f">start</span>(<span class="tk-k">async</span> (call) =&gt; {
262
+ <span class="tk-k">if</span> (call.kind === <span class="tk-s">"value"</span>) console.<span class="tk-f">log</span>(<span class="tk-s">"notes:"</span>, call.value); <span class="tk-c">// "failed" calls say a value cannot be computed now</span>
263
+ });</code></pre>
264
+ <p>A <strong>routine</strong> is the object watching on its own behalf: <code>self.on(source, fn)</code> runs <code>fn</code> with each new value, for as
265
+ long as the object lives (a reconciler: &quot;whenever the notes change, rebuild the export file&quot;).</p>
266
+ <p>A <strong>native</strong> is something outside Chord the object opens and must close: a file watcher, a database connection, a
267
+ child process. <code>self.open(open, close)</code> opens it while the object activates and closes it when the object ends:</p>
268
+ <pre><code><span class="tk-k">const</span> inbox = self.<span class="tk-f">open</span>(<span class="tk-k">async</span> (ctx) =&gt; <span class="tk-f">watchDirectory</span>(inboxPath, ctx.abortSignal), (watcher) =&gt; watcher.<span class="tk-f">close</span>());
269
+ self.<span class="tk-f">onLive</span>(<span class="tk-k">async</span> (ctx) =&gt; { <span class="tk-c">// a routine started once the object is live</span>
270
+ <span class="tk-k">for</span> <span class="tk-k">await</span> (<span class="tk-k">const</span> file <span class="tk-k">of</span> inbox.value.<span class="tk-f">files</span>(ctx.abortSignal)) <span class="tk-k">await</span> <span class="tk-f">importNote</span>(file, ctx);
271
+ });</code></pre>
272
+ <p>Natives are why some objects restart when their plugin changes: an open connection cannot be moved to new code, so
273
+ Chord closes it and opens it again. Objects without natives are swapped in place.</p>
274
+ </section>
275
+
276
+ <section class="chapter" id="hosts"><header class="opener"><div class="numeral">III</div><h2>Several Hosts</h2><p class="lede">A server, a worker per project, browser tabs: how they find each other&#39;s objects.</p></header>
277
+ <p class="dropcap">Now give each project its own process. Declare the kinds of addressable host, and make notes a <code>remote</code> type that
278
+ lives on its project&#39;s worker:</p>
279
+ <pre><code><span class="tk-k">export</span> <span class="tk-k">const</span> <span class="tk-t">Server</span> = <span class="tk-f">hostKind</span>(<span class="tk-s">"server"</span>);
280
+ <span class="tk-k">export</span> <span class="tk-k">const</span> <span class="tk-t">Project</span> = <span class="tk-f">hostKind</span>(<span class="tk-s">"project"</span>, { id: <span class="tk-f">str</span>() });
281
+
282
+ <span class="tk-k">export</span> <span class="tk-k">const</span> <span class="tk-t">Notes</span> = <span class="tk-f">remote</span>(<span class="tk-s">"notes"</span>, {
283
+ version: <span class="tk-n">1</span>,
284
+ params: { project: <span class="tk-f">str</span>() },
285
+ hostAddress: ({ project }) =&gt; <span class="tk-t">Project</span>({ id: project }), <span class="tk-c">// where an object of these params lives</span>
286
+ variants: { editor: { state: { list: <span class="tk-t">NoteList</span> }, methods: { add: <span class="tk-f">method</span>(<span class="tk-f">obj</span>({ text: <span class="tk-f">str</span>() })) } } },
287
+ });</code></pre>
288
+ <p>Two things are new. A <code>remote</code> type can be used from any host, and it has <strong>variants</strong>: different sets of members
289
+ for different callers, chosen by the factory (an <code>editor</code> variant with <code>add</code>, a <code>reader</code> variant for guests without
290
+ it). And <code>hostAddress</code> says where its objects live; it is the whole routing story.</p>
291
+ <p>A tab asks for <code>Notes { project: &quot;p1&quot; }</code>. Its host computes the address,
292
+ <code>Project(p1)</code>, and sends the request to its parent, the server. The server has a <strong>route</strong> for <code>Project</code>: it starts (or
293
+ finds) the worker for <code>p1</code> and passes the request on. The worker serves <code>Notes</code>. The tab gets a reference whose state
294
+ follows the worker&#39;s document, one frame per change.</p>
295
+ <figure class="fig wide anim"><svg viewBox="0 0 720 342" width="100%" role="img" aria-label="A tab holds a project's notes: the server routes by address to the project's worker and relays, without reading the data." xmlns="http://www.w3.org/2000/svg" style="font-family:'Avenir Next','Helvetica Neue',Helvetica,Arial,sans-serif;max-width:760px"><defs><marker id="f2m" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L8,4 L0,8 z" fill="#7b7468"/></marker><marker id="f2a" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L8,4 L0,8 z" fill="#b4472f"/></marker><marker id="f2b" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L8,4 L0,8 z" fill="#2e6a8a"/></marker></defs><text x="16" y="22" font-size="10" fill="#2e6a8a" text-anchor="start" font-weight="600" letter-spacing="2">CLIENTS</text><text x="16" y="144" font-size="10" fill="#b4472f" text-anchor="start" font-weight="600" letter-spacing="2">SERVER</text><text x="16" y="266" font-size="10" fill="#7b7468" text-anchor="start" font-weight="600" letter-spacing="2">WORKERS</text><g class="step" style="--i:1"><rect x="137" y="36" width="210" height="44" rx="4" fill="#fff" stroke="#c9bfae"/><text x="242" y="55.3" font-size="11" fill="#2a2723" text-anchor="middle">tab A</text><text x="242" y="69.3" font-size="9.5" fill="#7b7468" text-anchor="middle">holds Notes { project: p1 }</text></g><g class="step" style="--i:4"><rect x="373" y="36" width="210" height="44" rx="4" fill="#fff" stroke="#c9bfae"/><text x="478" y="55.3" font-size="11" fill="#2a2723" text-anchor="middle">tab B</text><text x="478" y="69.3" font-size="9.5" fill="#7b7468" text-anchor="middle">holds Notes { project: p1 }</text></g><g class="step" style="--i:3"><rect x="255" y="158" width="210" height="44" rx="4" fill="#fff" stroke="#c9bfae"/><text x="360" y="177.3" font-size="11" fill="#2a2723" text-anchor="middle">server</text><text x="360" y="191.3" font-size="9.5" fill="#7b7468" text-anchor="middle">route Project → worker</text></g><g class="step" style="--i:7"><rect x="137" y="280" width="210" height="44" rx="4" fill="#fff" stroke="#c9bfae"/><text x="242" y="299.3" font-size="11" fill="#2a2723" text-anchor="middle">worker p1</text><text x="242" y="313.3" font-size="9.5" fill="#7b7468" text-anchor="middle">serves Notes { p1 }</text></g><g class="step" style="--i:0"><rect x="373" y="280" width="210" height="44" rx="4" fill="#fff" stroke="#c9bfae"/><text x="478" y="299.3" font-size="11" fill="#2a2723" text-anchor="middle">worker p2</text><text x="478" y="313.3" font-size="9.5" fill="#7b7468" text-anchor="middle">serves Notes { p2 }</text></g><g class="step edge" style="--i:2"><path d="M242 80 L360 156" fill="none" stroke="#7b7468" marker-end="url(#f2m)"/><rect x="305" y="112" width="29.1" height="13" fill="#fbf8f2" opacity=".92"/><text x="309" y="122" font-size="9.5" fill="#7b7468" text-anchor="start">hold</text></g><g class="step edge" style="--i:5"><path d="M478 80 L360 156" fill="none" stroke="#7b7468" marker-end="url(#f2m)"/><rect x="423" y="112" width="29.1" height="13" fill="#fbf8f2" opacity=".92"/><text x="427" y="122" font-size="9.5" fill="#7b7468" text-anchor="start">hold</text></g><g class="step edge" style="--i:6"><path d="M360 202 L242 278" fill="none" stroke="#7b7468" marker-end="url(#f2m)"/><rect x="305" y="234" width="34.3" height="13" fill="#fbf8f2" opacity=".92"/><text x="309" y="244" font-size="9.5" fill="#7b7468" text-anchor="start">relay</text></g></svg><figcaption><button class="replay" type="button">Replay</button><span class="fignum">Figure 2.</span> A tab holds a project&#39;s notes: the server routes by address to the project&#39;s worker and relays, without reading the data.</figcaption></figure>
296
+ <p>Each host is created the same way, with what it is:</p>
297
+ <pre><code><span class="tk-c">// server.ts</span>
298
+ <span class="tk-k">const</span> server = <span class="tk-f">createHost</span>&lt;P&gt;({ address: <span class="tk-t">Server</span>(), principal: { kind: <span class="tk-s">"server"</span> }, onError });
299
+
300
+ <span class="tk-c">// worker.ts (started by the server for one project)</span>
301
+ <span class="tk-k">const</span> worker = <span class="tk-f">createHost</span>&lt;P&gt;({ address: <span class="tk-t">Project</span>({ id }), principal: { kind: <span class="tk-s">"worker"</span>, project: id }, onError });
302
+ worker.<span class="tk-f">connect</span>(parentLink, { principal: { kind: <span class="tk-s">"server"</span> }, trusted: <span class="tk-k">true</span> }, ctx);
303
+
304
+ <span class="tk-c">// a browser tab: no address, it is a client</span>
305
+ <span class="tk-k">const</span> tab = <span class="tk-f">createHost</span>&lt;P&gt;({ onError });
306
+ tab.<span class="tk-f">connect</span>(<span class="tk-f">webSocketLink</span>(<span class="tk-k">new</span> <span class="tk-t">WebSocket</span>(<span class="tk-s">"/chord"</span>)), { principal: { kind: <span class="tk-s">"server"</span> } }, ctx);</code></pre>
307
+ <p><code>P</code> is your app&#39;s type of <strong>principal</strong>, who is calling: an owner, a guest, the server, a worker. Links stamp it;
308
+ a <code>remote</code> object is made per principal, so a guest can get a read-only variant of the same notes.</p>
309
+ <div class="note"><b class="tag">Coming with the app kit</b><p>Starting workers, routing a host kind to them, the WebSocket entry and authentication are slice 10&#39;s components today
310
+ (<code>createWorkers</code>, <code>chord.http</code>), wired by the app. The opinionated app kit (<code>chord/next/app</code>, being designed) will do
311
+ this wiring for you: <code>startApp(...)</code> and <code>startWorker()</code>.</p>
312
+ </div>
313
+ </section>
314
+
315
+ <section class="chapter" id="clients"><header class="opener"><div class="numeral">IV</div><h2>Client Hosts</h2><p class="lede">Browser tabs and terminal UIs are hosts too: what they can do, and what they cannot.</p></header>
316
+ <p class="dropcap">A browser tab and a terminal UI are hosts like the server, with one difference: they have <strong>no address</strong>. Nobody can
317
+ send a request <em>to</em> a tab; a tab only connects to the server and asks for things. That is a deliberate rule: a tab
318
+ runs on a device the server does not control, so nothing on the server ever waits for, or trusts, a tab&#39;s state.</p>
319
+ <pre><code><span class="tk-c">// a browser tab (slice 11's page host will do this wiring for you)</span>
320
+ <span class="tk-k">const</span> tab = <span class="tk-f">createHost</span>&lt;P&gt;({ onError }); <span class="tk-c">// no address, no principal: a client</span>
321
+ tab.<span class="tk-f">connect</span>(<span class="tk-f">webSocketLink</span>(<span class="tk-k">new</span> <span class="tk-t">WebSocket</span>(<span class="tk-s">"/chord"</span>)), { principal: { kind: <span class="tk-s">"server"</span> } }, ctx);
322
+ <span class="tk-k">await</span> tab.<span class="tk-f">load</span>([{ name: <span class="tk-s">"@app/web"</span>, facet: webCore }, ...webFacets], ctx);
323
+
324
+ <span class="tk-k">const</span> notes = tab.<span class="tk-f">hold</span>(<span class="tk-t">Notes</span>, { project: <span class="tk-s">"p1"</span> }, ctx); <span class="tk-c">// a reference at once, live soon</span>
325
+ (<span class="tk-k">await</span> notes.list.<span class="tk-f">watch</span>(ctx)).<span class="tk-f">start</span>(<span class="tk-k">async</span> (call) =&gt; {
326
+ <span class="tk-k">if</span> (call.kind === <span class="tk-s">"value"</span>) <span class="tk-f">render</span>(call.value.items); <span class="tk-c">// every change, as it commits on the worker</span>
327
+ });
328
+ <span class="tk-k">await</span> notes.<span class="tk-f">add</span>({ text: <span class="tk-s">"from the tab"</span> }, ctx); <span class="tk-c">// a call: tab → server → worker</span></code></pre>
329
+ <p><strong>Who the tab is</strong> is not the tab&#39;s to say. The server authenticates the WebSocket when it connects (a cookie, the
330
+ owner on loopback, a guest&#39;s share link) and stamps that principal on everything the tab asks for. The worker&#39;s
331
+ <code>Notes</code> factory receives it and may give a guest a read-only variant. A tab cannot claim to be the owner.</p>
332
+ <p><strong>What a tab serves</strong> is only <code>local</code> types: state of this tab&#39;s UI, never shared. A draft that survives switching
333
+ panels, a selection, a tab-local cache:</p>
334
+ <pre><code><span class="tk-c">// plugins/notes/web.tsx: the web facet serves a local type, and contributes a panel</span>
335
+ <span class="tk-k">export</span> <span class="tk-k">default</span> <span class="tk-f">defineFacet</span>((host, self) =&gt; {
336
+ host.<span class="tk-f">serve</span>(<span class="tk-t">NoteDraft</span>, (_params, self) =&gt; ({ text: self.<span class="tk-f">state</span>(<span class="tk-t">DraftDoc</span>) })); <span class="tk-c">// lives in this tab only</span>
337
+ self.<span class="tk-f">contribute</span>(<span class="tk-t">Panels</span>, { title: <span class="tk-s">"Notes"</span>, <span class="tk-t">Component</span>: <span class="tk-t">NotesPanel</span> });
338
+ });</code></pre>
339
+ <p><strong>When the connection drops</strong> (a phone in a tunnel, a server restart), the tab keeps its references. Their values
340
+ stay readable, their <code>state</code> says <code>loading</code>, calls made meanwhile wait; on reconnect every reference is held again and
341
+ gets the current value in one frame. The UI shows a banner from <code>ref.state</code>, nothing more.</p>
342
+ <p><strong>A terminal UI</strong> is the same in Node: a client host connected to the server over a WebSocket, loading the plugins&#39;
343
+ <code>tui</code> facets, rendering with whatever terminal library the app chose. <strong>What a client never does</strong>: serve a <code>remote</code>
344
+ type, be routed to, or keep data others rely on. Data that must outlive a tab belongs in an object on the server or a
345
+ worker.</p>
346
+ </section>
347
+
348
+ <section class="chapter" id="plugins"><header class="opener"><div class="numeral">V</div><h2>Plugins</h2><p class="lede">Move the code into a directory that can be added, edited and removed while the app runs.</p></header>
349
+ <p class="dropcap">So far the facets were part of the app&#39;s own code. A <strong>plugin</strong> is the same code in its own directory:</p>
350
+ <pre class="plain"><code>plugins/notes/
351
+ package.json { "name": "@app/notes" }
352
+ contract.ts the Notes contract (other plugins import it)
353
+ worker.ts the facet for workers: serves Notes
354
+ server.ts the facet for the server: an export route
355
+ web.tsx the facet for browser tabs: a notes panel</code></pre>
356
+ <p>The plugin&#39;s name is its <code>package.json</code> name. Each file named after a <strong>host kind</strong> is that kind&#39;s facet, its
357
+ default export a <code>defineFacet(...)</code>. A plugin has only the files it needs: a plugin that only adds a route has a
358
+ <code>server.ts</code> and nothing else.</p>
359
+ <pre><code><span class="tk-c">// plugins/notes/worker.ts</span>
360
+ <span class="tk-k">import</span> { defineFacet } <span class="tk-k">from</span> <span class="tk-s">"@app/core"</span>;
361
+ <span class="tk-k">import</span> { <span class="tk-t">Notes</span> } <span class="tk-k">from</span> <span class="tk-s">"./contract.ts"</span>;
362
+
363
+ <span class="tk-k">export</span> <span class="tk-k">default</span> <span class="tk-f">defineFacet</span>((host) =&gt; {
364
+ host.<span class="tk-f">serve</span>(<span class="tk-t">Notes</span>, ({ project }, principal, self) =&gt; {
365
+ <span class="tk-k">const</span> doc = self.<span class="tk-f">state</span>(<span class="tk-t">NotesDoc</span>);
366
+ <span class="tk-k">return</span> { variant: <span class="tk-s">"editor"</span>, members: { list: doc, add: <span class="tk-k">async</span> ({ text }, ctx) =&gt; <span class="tk-c">/* … */</span> } };
367
+ });
368
+ });</code></pre>
369
+ <p><code>@app/core</code> is your app&#39;s <strong>base code</strong>, imported by every plugin as a host package (the plugin&#39;s build leaves it
370
+ out; every host passes its own copy in). It holds what plugins share and never reloads: host kinds, the principal
371
+ type, a <code>defineFacet</code> bound to it.</p>
372
+ </section>
373
+
374
+ <section class="chapter" id="loading"><header class="opener"><div class="numeral">VI</div><h2>Loading Plugins</h2><p class="lede">Two steps in two places: building a plugin into a script happens once, on the server; evaluating it happens in every process that runs it.</p></header>
375
+ <p class="dropcap">A plugin is source code on the server&#39;s disk: TypeScript files that import each other, import other plugins&#39;
376
+ contracts, import npm packages, and import things the app itself provides. None of the processes that run the plugin
377
+ can use those files as they are. A browser tab has no file system and no TypeScript; a worker could read the files,
378
+ but then every worker would compile every plugin again, and two workers started a minute apart could see two different
379
+ versions. So loading a plugin is two separate steps:</p>
380
+ <ol>
381
+ <li><strong>Build</strong>: turn each plugin facet (<code>notes/worker.ts</code>, <code>notes/web.tsx</code>) into one self-contained <strong>script</strong>. This
382
+ happens once per edit, on the server, for every host kind.</li>
383
+ <li><strong>Evaluate</strong>: run a script inside one process, which gives back the facet, ready for <code>host.load</code>. This happens in
384
+ every process that hosts that kind: the server for its own facets, each worker for the worker facets, each tab for
385
+ the web facets.</li>
386
+ </ol>
387
+ <p>The two steps need different things, and that is why the API has two calls.</p>
388
+ <h3 id="host-packages-what-a-script-leaves-out">Host packages: what a script leaves out</h3>
389
+ <p>Look at what <code>notes/worker.ts</code> imports:</p>
390
+ <pre><code><span class="tk-k">import</span> { defineFacet, <span class="tk-t">Session</span> } <span class="tk-k">from</span> <span class="tk-s">"@app/core"</span>; <span class="tk-c">// the app's base code</span>
391
+ <span class="tk-k">import</span> { obj, str, remote } <span class="tk-k">from</span> <span class="tk-s">"@earendil-works/chord/next"</span>; <span class="tk-c">// Chord itself</span>
392
+ <span class="tk-k">import</span> { <span class="tk-t">Notes</span> } <span class="tk-k">from</span> <span class="tk-s">"./contract.ts"</span>; <span class="tk-c">// the plugin's own file</span>
393
+ <span class="tk-k">import</span> slugify <span class="tk-k">from</span> <span class="tk-s">"slugify"</span>; <span class="tk-c">// an npm package in the plugin's dependencies</span></code></pre>
394
+ <p>The last two go into the script: the plugin&#39;s own files and its npm dependencies are copied in. The first two must
395
+ not. If the script carried its own copy of Chord, the worker would run two Chords: the plugin&#39;s <code>ChordError</code> would not
396
+ be the worker&#39;s <code>ChordError</code>, and the plugin&#39;s <code>defineFacet</code> would make a facet the worker&#39;s host does not recognize.
397
+ The same holds for <code>@app/core</code>: the plugin must see the very <code>Session</code> host kind and the very <code>Panels</code> registry the
398
+ process already has, not a copy.</p>
399
+ <p>Packages the process already has, and that every plugin must share, are its <strong>host packages</strong>. A script leaves them
400
+ out and asks for them by name when it runs. Building therefore needs only their <strong>names</strong>: &quot;do not copy
401
+ <code>@earendil-works/chord/next</code> or <code>@app/core</code> into this script&quot;.</p>
402
+ <h3 id="building-createplugins-on-the-server">Building: <code>createPlugins</code>, on the server</h3>
403
+ <pre><code><span class="tk-k">const</span> plugins = <span class="tk-f">createPlugins</span>({
404
+ roots: [<span class="tk-s">"./plugins"</span>], <span class="tk-c">// where the plugin directories are</span>
405
+ kinds: {
406
+ server: { platform: <span class="tk-s">"node"</span>, hostPackages: [<span class="tk-s">"@earendil-works/chord/next"</span>, <span class="tk-s">"@app/core"</span>] },
407
+ worker: { platform: <span class="tk-s">"node"</span>, hostPackages: [<span class="tk-s">"@earendil-works/chord/next"</span>, <span class="tk-s">"@app/core"</span>] },
408
+ web: { platform: <span class="tk-s">"browser"</span>, hostPackages: [<span class="tk-s">"@earendil-works/chord/next"</span>, <span class="tk-s">"@app/core"</span>, <span class="tk-s">"react"</span>, <span class="tk-s">"react/jsx-runtime"</span>] },
409
+ },
410
+ onError,
411
+ }, ctx);</code></pre>
412
+ <p><code>createPlugins</code> is the builder, and it builds for every kind, because only the server has the sources. For each kind
413
+ it needs two facts. The <strong>platform</strong> says where the scripts run: a <code>node</code> script may import <code>node:fs</code>, a <code>browser</code>
414
+ script may import a stylesheet but not <code>node:fs</code>. The <strong>host package names</strong> say what to leave out; they differ per
415
+ kind, because a tab also shares React with its plugins and a worker does not. Nothing here runs a plugin.</p>
416
+ <h3 id="evaluating-plugins-load-in-the-process-that-hosts">Evaluating: <code>plugins.load</code>, in the process that hosts</h3>
417
+ <p>Evaluating is where the names become things. When the script runs and asks for <code>@app/core</code>, someone has to hand it
418
+ the actual module, the one this process imported when it started. Only the process itself has it:</p>
419
+ <pre><code><span class="tk-c">// server.ts</span>
420
+ <span class="tk-k">import</span> * <span class="tk-k">as</span> chord <span class="tk-k">from</span> <span class="tk-s">"@earendil-works/chord/next"</span>;
421
+ <span class="tk-k">import</span> * <span class="tk-k">as</span> core <span class="tk-k">from</span> <span class="tk-s">"./core.ts"</span>; <span class="tk-c">// the app's base code, the same module plugins import as "@app/core"</span>
422
+
423
+ <span class="tk-k">const</span> report = <span class="tk-k">await</span> plugins.<span class="tk-f">load</span>(server, {
424
+ kind: <span class="tk-s">"server"</span>, <span class="tk-c">// evaluate the server kind's scripts</span>
425
+ modules: { <span class="tk-s">"@earendil-works/chord/next"</span>: chord, <span class="tk-s">"@app/core"</span>: core }, <span class="tk-c">// this process's own instances</span>
426
+ core: [{ name: <span class="tk-s">"@app/core"</span>, facet: core.serverFacet }], <span class="tk-c">// base-code facets, loaded beside the plugins</span>
427
+ }, ctx);</code></pre>
428
+ <p><code>modules</code> is this process&#39;s answer to every host package name. The server passes its own; a worker passes its own in
429
+ <code>workerMain</code>; a page passes its own in <code>startPage</code>. Each process has different instances, which is exactly the point:
430
+ inside each process, plugins share that process&#39;s Chord and base code.</p>
431
+ <p><code>core</code> is the app&#39;s base code in facet form. It is a facet like a plugin&#39;s, but it is not a plugin: it is made in the
432
+ process&#39;s own code, often from values only this process has (<code>core.workerFacet(start)</code> closes over a worker&#39;s start
433
+ data and store), and it never reloads, because it defines what all plugins share. Passing it here loads it together
434
+ with the plugins, so they are published in one step.</p>
435
+ <h3 id="why-plugins-load-host-not-host-load">Why <code>plugins.load(host)</code>, not <code>host.load</code></h3>
436
+ <p>A host has its own <code>load</code>, and <code>plugins.load</code> calls it. The host&#39;s <code>load</code> takes facets that already exist: functions
437
+ in memory. It knows nothing about directories, builds, scripts or modules, on purpose: the same host runs in a test
438
+ with facets imported directly, or in a Cloudflare Durable Object where plugins are bundled at deploy time and nothing
439
+ is built or evaluated at runtime.</p>
440
+ <p>The plugins component is the part that knows about directories. It finds the plugins, builds them, evaluates them
441
+ with the process&#39;s modules, and then calls <code>host.load</code> with the result. It also remembers, per host, which facet each
442
+ plugin runs, so that a later reload can hand the host its complete new plugin set, with unchanged plugins as the very
443
+ same objects. That memory is why the host is passed to it: <code>plugins.load(server, …)</code> on the server,
444
+ <code>plugins.load(worker, …)</code> in a worker (where <code>workerMain</code> gives it a <code>plugins</code> that only evaluates), the same call
445
+ in every process.</p>
446
+ <figure class="fig wide"><svg viewBox="0 0 720 242" width="100%" role="img" aria-label="Building on the server needs names; evaluating in each process needs that process's modules." xmlns="http://www.w3.org/2000/svg" style="font-family:'Avenir Next','Helvetica Neue',Helvetica,Arial,sans-serif;max-width:760px"><defs><marker id="f3m" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L8,4 L0,8 z" fill="#7b7468"/></marker><marker id="f3a" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L8,4 L0,8 z" fill="#b4472f"/></marker><marker id="f3b" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L8,4 L0,8 z" fill="#2e6a8a"/></marker></defs><text x="16" y="22" font-size="10" fill="#b4472f" text-anchor="start" font-weight="600" letter-spacing="2">SERVER: BUILD (ONCE PER EDIT)</text><text x="16" y="155" font-size="10" fill="#2e6a8a" text-anchor="start" font-weight="600" letter-spacing="2">EACH WORKER: EVALUATE</text><rect x="19" y="36" width="210" height="55" rx="4" fill="#efe9dd" stroke="#c9bfae"/><text x="124" y="54.5" font-size="11" fill="#2a2723" text-anchor="middle">plugin sources</text><text x="124" y="68.5" font-size="9.5" fill="#7b7468" text-anchor="middle" font-family="Menlo,monospace">notes/worker.ts`, imports</text><text x="124" y="81" font-size="9.5" fill="#7b7468" text-anchor="middle" font-family="Menlo,monospace">`@app/core</text><rect x="255" y="36" width="210" height="55" rx="4" fill="#fff" stroke="#b4472f" stroke-width="1.5"/><text x="360" y="54.5" font-size="11" fill="#2a2723" text-anchor="middle">createPlugins</text><text x="360" y="68.5" font-size="9.5" fill="#7b7468" text-anchor="middle">copies own files and npm deps; leaves</text><text x="360" y="81" font-size="9.5" fill="#7b7468" text-anchor="middle">host packages out</text><rect x="491" y="36" width="210" height="55" rx="4" fill="#fff" stroke="#c9bfae"/><text x="596" y="60.8" font-size="11" fill="#2a2723" text-anchor="middle">worker script</text><text x="596" y="74.8" font-size="9.5" fill="#7b7468" text-anchor="middle">`require(&quot;@app/core&quot;)` left as a name</text><rect x="19" y="169" width="210" height="55" rx="4" fill="#efe9dd" stroke="#c9bfae"/><text x="124" y="193.8" font-size="11" fill="#2a2723" text-anchor="middle">the worker's modules</text><text x="124" y="207.8" font-size="9.5" fill="#7b7468" text-anchor="middle">its own `@app/core`, its own Chord</text><rect x="255" y="169" width="210" height="55" rx="4" fill="#fff" stroke="#2e6a8a" stroke-width="1.5"/><text x="360" y="193.8" font-size="11" fill="#2a2723" text-anchor="middle">plugins.load(worker, …)</text><text x="360" y="207.8" font-size="9.5" fill="#7b7468" text-anchor="middle">runs the script, answers each name</text><rect x="491" y="169" width="210" height="55" rx="4" fill="#fff" stroke="#c9bfae"/><text x="596" y="187.5" font-size="11" fill="#2a2723" text-anchor="middle">the facet</text><text x="596" y="201.5" font-size="9.5" fill="#7b7468" text-anchor="middle">uses the worker's `Session`, the</text><text x="596" y="214" font-size="9.5" fill="#7b7468" text-anchor="middle">worker's `defineFacet`</text><path d="M229 63.5 L253 63.5" fill="none" stroke="#7b7468" marker-end="url(#f3m)"/><path d="M465 63.5 L489 63.5" fill="none" stroke="#7b7468" marker-end="url(#f3m)"/><path d="M596 91 L360 167" fill="none" stroke="#7b7468" marker-end="url(#f3m)"/><rect x="482" y="123" width="44.9" height="13" fill="#fbf8f2" opacity=".92"/><text x="486" y="133" font-size="9.5" fill="#7b7468" text-anchor="start">shipped</text><path d="M229 196.5 L253 196.5" fill="none" stroke="#7b7468" marker-end="url(#f3m)"/><path d="M465 196.5 L489 196.5" fill="none" stroke="#7b7468" marker-end="url(#f3m)"/></svg><figcaption><span class="fignum">Figure 3.</span> Building on the server needs names; evaluating in each process needs that process&#39;s modules.</figcaption></figure>
447
+ <h3 id="what-happens-step-by-step">What happens, step by step</h3>
448
+ <div class="steps"><div class="steps-head"><span class="title"><code>plugins.load(server, { kind: &quot;server&quot;, … })</code></span><span class="count"></span><button class="prev" type="button">Back</button><button class="next" type="button">Next</button></div><div class="step-panel"><h4>Discover</h4><p>The component lists <code>./plugins</code> one level deep and reads each <code>package.json</code>. Its <code>name</code> is the plugin&#39;s name; the
449
+ files named after a kind are its facets. A directory without a <code>package.json</code>, or with two <code>server</code> files, is reported,
450
+ not loaded.</p>
451
+ </div><div class="step-panel"><h4>Build</h4><p>For each plugin with a <code>server</code> facet it builds one script, if no current one exists. A syntax error or an import the
452
+ rules do not allow (a path into base code, a package not in the plugin&#39;s dependencies) is a failed build with the file
453
+ and line, never a crash.</p>
454
+ </div><div class="step-panel"><h4>Evaluate</h4><p>The script runs. Each host package name it asks for is answered from <code>modules</code>; anything else it may not have. The
455
+ script&#39;s default export must be a facet.</p>
456
+ </div><div class="step-panel"><h4>Load</h4><p><code>host.load</code> runs the setups of <code>core</code> and of every plugin facet and publishes them together. A plugin whose build,
457
+ evaluation or setup failed is left out and listed in <code>report.failed</code> with the reason; the others load. Objects that
458
+ need it wait until a later edit loads it.</p>
459
+ </div></div>
460
+ <p>Only the server builds. Workers and clients (browser tabs, terminal UIs) only evaluate: the server builds their kinds
461
+ too, a worker gets its scripts in its start message, a tab or a TUI gets them from the server over HTTP, and each
462
+ evaluates them with its own modules (a worker&#39;s from <code>workerMain</code>, a page&#39;s from its base bundle).</p>
463
+ </section>
464
+
465
+ <section class="chapter" id="together"><header class="opener"><div class="numeral">VII</div><h2>Plugins Using Plugins</h2><p class="lede">Two ways one plugin uses another, and the one it may not.</p></header>
466
+ <p class="dropcap">A search plugin wants to search the notes. It <strong>imports the contract</strong> and asks for the object:</p>
467
+ <pre><code><span class="tk-c">// plugins/search/worker.ts</span>
468
+ <span class="tk-k">import</span> { <span class="tk-t">Notes</span> } <span class="tk-k">from</span> <span class="tk-s">"@app/notes/contract"</span>; <span class="tk-c">// another plugin, by its name: copied into search's script</span>
469
+
470
+ host.<span class="tk-f">serve</span>(<span class="tk-t">Search</span>, ({ project }, principal, self) =&gt; {
471
+ <span class="tk-k">const</span> notes = self.<span class="tk-f">get</span>(<span class="tk-t">Notes</span>, { project }); <span class="tk-c">// a dependency: Search goes live once Notes is</span>
472
+ <span class="tk-k">const</span> index = self.<span class="tk-f">derive</span>([notes.list], ([list]) =&gt; <span class="tk-f">buildIndex</span>(list.items));
473
+ <span class="tk-k">return</span> { variant: <span class="tk-s">"main"</span>, members: { find: <span class="tk-k">async</span> ({ q }) =&gt; <span class="tk-f">lookup</span>(index.value, q) } };
474
+ });</code></pre>
475
+ <p>A plugin imports another plugin by its <strong>name</strong>, never by a path: <code>@app/notes/contract</code> is the file <code>contract.ts</code> of
476
+ whichever discovered plugin is named <code>@app/notes</code>, in any root. The file is copied into the importer&#39;s script, so only
477
+ contracts and other side-effect-free files belong there; a missing plugin is a build error naming it.</p>
478
+ <p><code>self.get</code> in a factory declares a dependency: Chord makes <code>Search</code> live only once <code>Notes</code> is, and if the notes
479
+ plugin is missing, <code>Search</code> waits with a clear reason (&quot;waiting for notes: not served here&quot;) instead of failing.</p>
480
+ <p>The other way is a <strong>registry</strong>: an extension point one plugin defines and others contribute to. The app&#39;s core
481
+ defines <code>Panels</code>, and every plugin with a UI contributes one:</p>
482
+ <pre><code><span class="tk-c">// plugins/notes/web.tsx</span>
483
+ <span class="tk-k">export</span> <span class="tk-k">default</span> <span class="tk-f">defineFacet</span>((host, self) =&gt; self.<span class="tk-f">contribute</span>(<span class="tk-t">Panels</span>, { title: <span class="tk-s">"Notes"</span>, <span class="tk-t">Component</span>: <span class="tk-t">NotesPanel</span> }));</code></pre>
484
+ <p>What a plugin may not do is reach into another&#39;s data. Search never reads notes&#39; documents; it uses the <code>Notes</code>
485
+ object&#39;s state. That rule is what lets the notes plugin change its storage without breaking search.</p>
486
+ </section>
487
+
488
+ <section class="chapter" id="reload"><header class="opener"><div class="numeral">VIII</div><h2>Changing a Plugin</h2><p class="lede">Edit, build, roll out: how new code takes over while every tab stays connected.</p></header>
489
+ <p class="dropcap">You change the notes plugin: notes now have a timestamp. The watcher sees the saved file and marks the plugin dirty.
490
+ You (or an agent) build and roll out:</p>
491
+ <pre><code><span class="tk-k">const</span> built = <span class="tk-k">await</span> plugins.<span class="tk-f">build</span>(plugins.state.value.dirty, ctx);
492
+ <span class="tk-k">const</span> result = <span class="tk-k">await</span> plugins.<span class="tk-f">rollout</span>([plugins.<span class="tk-f">step</span>(<span class="tk-s">"server"</span>, server), workers.<span class="tk-f">step</span>(<span class="tk-s">"workers"</span>)], built, ctx);</code></pre>
493
+ <p>The rollout goes host by host, server first, then every running worker. On each host Chord compares the new plugin
494
+ set with the loaded one, runs the new factories against a recording <code>self</code> to see what each object would declare, and
495
+ then gives every object of the changed plugin its fate:</p>
496
+ <table>
497
+ <thead>
498
+ <tr>
499
+ <th>The object</th>
500
+ <th>What happens</th>
501
+ </tr>
502
+ </thead>
503
+ <tbody><tr>
504
+ <td>holds no natives (open files, sockets), the new code neither</td>
505
+ <td><strong>swapped</strong> in place: new methods, same documents; running calls finish on the old code</td>
506
+ </tr>
507
+ <tr>
508
+ <td>holds natives</td>
509
+ <td><strong>restarted</strong>: calls wait, running ones finish, natives close and reopen with the new code</td>
510
+ </tr>
511
+ <tr>
512
+ <td>its type was removed</td>
513
+ <td><strong>ended</strong>; its users wait until something serves it again</td>
514
+ </tr>
515
+ </tbody></table>
516
+ <p>The tab&#39;s reference follows the new object and gets one frame with the difference. Nothing reconnects. If the edit
517
+ is broken (a syntax error, a factory that throws), that plugin keeps its old code on that host and the report says why;
518
+ every other plugin of the rollout applies.</p>
519
+ <div class="note"><b class="tag">Versions</b><p>A change to a contract (a new field in <code>Notes</code>&#39;s state) gets a new <code>version</code>. A tab built with the old contract keeps
520
+ working if the provider maps the old version (<code>accepts</code>); otherwise it waits with &quot;version mismatch&quot; until it reloads.</p>
521
+ </div>
522
+ </section>
523
+
524
+ <section class="chapter" id="base"><header class="opener"><div class="numeral">IX</div><h2>Base Code and Plugins</h2><p class="lede">What goes into the app itself, what goes into plugins, and how an app ships plugins of its own.</p></header>
525
+ <p class="dropcap">Every app has two kinds of code, and the line between them decides what can change while the app runs.</p>
526
+ <p><strong>Base code</strong> is the app&#39;s own program: <code>src/</code>, started by <code>node server.ts</code>. It is what every plugin shares: the host
527
+ kinds (<code>Server</code>, <code>Project</code>), the principal type, the app&#39;s <code>defineFacet</code>, the registries plugins contribute to
528
+ (<code>Panels</code>), and the startup that creates hosts and loads plugins. Plugins import it as a host package (<code>@app/core</code>),
529
+ so inside one process there is exactly one of each. Base code changes only with a restart: if it reloaded, the
530
+ process would hold two <code>Panels</code> registries, and old and new plugins would no longer meet.</p>
531
+ <p><strong>Plugins</strong> are features: notes, search, export, a terminal. They reload on an edit, a broken one is left out alone,
532
+ and an agent can write one while the app runs.</p>
533
+ <p>The rule: <strong>base code is what everything shares, not features.</strong> A feature in base code cannot be edited live, and a
534
+ bug in it needs a restart. Keep base code to host kinds, principals, shared registries and startup.</p>
535
+ <h3 id="plugins-the-app-ships">Plugins the app ships</h3>
536
+ <p>An app usually comes with plugins of its own: notes, search, settings. They are still plugins, kept in a root inside
537
+ the app, next to the root where users and agents add theirs:</p>
538
+ <pre><code><span class="tk-k">const</span> plugins = <span class="tk-f">createPlugins</span>({
539
+ roots: [<span class="tk-s">"./src/plugins"</span>, <span class="tk-f">join</span>(dataDir, <span class="tk-s">"plugins"</span>)], <span class="tk-c">// the app's own plugins, then the user's</span>
540
+ kinds,
541
+ onError,
542
+ }, ctx);</code></pre>
543
+ <p>They are built at startup like any plugin (a quarter of a second for twenty), reload like any plugin, and are left
544
+ out alone when broken. If two roots have a plugin with the same name, the first root wins, and the other is reported.</p>
545
+ <h3 id="subpaths-of-host-packages">Subpaths of host packages</h3>
546
+ <p>A host package is matched by its exact name. If base code offers several entry points (<code>@app/core</code> for every host,
547
+ <code>@app/core/web</code> for pages), each is its own host package, listed by name for the build and given as a module when
548
+ evaluating, as <code>react</code> and <code>react/jsx-runtime</code> are. A plugin importing a subpath that is not listed gets a build
549
+ error naming it.</p>
550
+ <h3 id="what-the-app-kit-will-change">What the app kit will change</h3>
551
+ <p>The app kit being designed next (<code>chord/next/app</code>) will make the base code nearly empty: <code>startApp</code> and <code>startWorker</code>
552
+ with Chord&#39;s conventions for hosts, users, authentication and storage. An app is then its plugins, its own ones in
553
+ <code>src/plugins</code> and the user&#39;s beside them.</p>
554
+ </section>
555
+
556
+ <section class="chapter appendix" id="reference"><header class="opener"><div class="numeral">A</div><h2>Reference</h2></header>
557
+ <table>
558
+ <thead>
559
+ <tr>
560
+ <th>Call</th>
561
+ <th>What it does</th>
562
+ </tr>
563
+ </thead>
564
+ <tbody><tr>
565
+ <td><code>createHost&lt;P&gt;({ address?, principal?, store?, onError })</code></td>
566
+ <td>a host: addressable with an address, else a client</td>
567
+ </tr>
568
+ <tr>
569
+ <td><code>host.load([{ name, facet }], ctx)</code> / <code>host.reload(...)</code></td>
570
+ <td>publish facets / apply a new plugin set</td>
571
+ </tr>
572
+ <tr>
573
+ <td><code>host.get(Type, params, ctx)</code> / <code>host.hold(...)</code></td>
574
+ <td>a live reference / a reference at once that follows its object</td>
575
+ </tr>
576
+ <tr>
577
+ <td><code>local(name, { version, params, members })</code> / <code>remote(name, { version, params, hostAddress, variants })</code></td>
578
+ <td>contracts</td>
579
+ </tr>
580
+ <tr>
581
+ <td><code>defineFacet((host, self) =&gt; …)</code>, <code>host.serve(Type, factory)</code>, <code>self.contribute(R, value)</code></td>
582
+ <td>a facet</td>
583
+ </tr>
584
+ <tr>
585
+ <td>factory <code>self</code>: <code>state</code>, <code>derive</code>, <code>get</code>, <code>registry</code>, <code>open</code>, <code>on</code>, <code>onLive</code>, <code>job</code>, <code>tx</code></td>
586
+ <td>an object&#39;s parts</td>
587
+ </tr>
588
+ <tr>
589
+ <td><code>createPlugins({ roots, kinds, onError }, ctx)</code></td>
590
+ <td>the plugins component</td>
591
+ </tr>
592
+ <tr>
593
+ <td><code>plugins.load(host, { kind, core, modules }, ctx)</code>, <code>build(names)</code>, <code>rollout(steps, built)</code></td>
594
+ <td>load, build, roll out</td>
595
+ </tr>
596
+ <tr>
597
+ <td><code>hostKind(name, params?)</code>, <code>Kind(params)</code></td>
598
+ <td>host kinds and addresses</td>
599
+ </tr>
600
+ </tbody></table>
601
+ </section>
602
+
603
+ <p class="colophon">Hosts and Plugins · first edition · 2026-10-31 · Chord v2 slices 1-10</p>
604
+ </div></div>
605
+ <script>(function activate(root) {
606
+ const replay = (f) => {
607
+ f.classList.remove("play");
608
+ void f.getBoundingClientRect();
609
+ f.classList.add("play");
610
+ };
611
+ const io = new IntersectionObserver(
612
+ (es) => {
613
+ for (const e of es)
614
+ if (e.isIntersecting) {
615
+ e.target.classList.add("play");
616
+ io.unobserve(e.target);
617
+ }
618
+ },
619
+ { threshold: 0.3 },
620
+ );
621
+ root.querySelectorAll(".anim:not(.armed)").forEach((f) => {
622
+ f.classList.add("armed");
623
+ io.observe(f);
624
+ const b = f.querySelector(".replay");
625
+ if (b) b.onclick = () => replay(f);
626
+ });
627
+ root.querySelectorAll(".steps:not(.js)").forEach((s) => {
628
+ s.classList.add("js");
629
+ const ps = [...s.querySelectorAll(":scope>.step-panel")];
630
+ let i = 0;
631
+ const c = s.querySelector(".count"),
632
+ p = s.querySelector(".prev"),
633
+ n = s.querySelector(".next");
634
+ const show = () => {
635
+ ps.forEach((x, j) => x.classList.toggle("on", j === i));
636
+ c.textContent = `${i + 1} / ${ps.length}`;
637
+ p.disabled = i === 0;
638
+ n.disabled = i === ps.length - 1;
639
+ ps[i].querySelectorAll(".anim").forEach(replay);
640
+ };
641
+ p.onclick = () => {
642
+ i--;
643
+ show();
644
+ };
645
+ n.onclick = () => {
646
+ i++;
647
+ show();
648
+ };
649
+ show();
650
+ });
651
+ })(document)</script>
652
+ </body></html>