@haverstack/core 0.40.0 → 0.42.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 (287) hide show
  1. package/README.md +121 -59
  2. package/dist/access.d.ts +34 -36
  3. package/dist/access.d.ts.map +1 -1
  4. package/dist/access.js +65 -42
  5. package/dist/access.js.map +1 -1
  6. package/dist/{combine.d.ts → adapter/combine.d.ts} +8 -1
  7. package/dist/adapter/combine.d.ts.map +1 -0
  8. package/dist/{combine.js → adapter/combine.js} +7 -0
  9. package/dist/adapter/combine.js.map +1 -0
  10. package/dist/{adapter-entry.d.ts → adapter/index.d.ts} +6 -5
  11. package/dist/adapter/index.d.ts.map +1 -0
  12. package/dist/{adapter-entry.js → adapter/index.js} +5 -4
  13. package/dist/adapter/index.js.map +1 -0
  14. package/dist/{sort.d.ts → adapter/sort.d.ts} +20 -20
  15. package/dist/adapter/sort.d.ts.map +1 -0
  16. package/dist/{sort.js → adapter/sort.js} +37 -27
  17. package/dist/adapter/sort.js.map +1 -0
  18. package/dist/associations/identity.d.ts +93 -0
  19. package/dist/associations/identity.d.ts.map +1 -0
  20. package/dist/associations/identity.js +198 -0
  21. package/dist/associations/identity.js.map +1 -0
  22. package/dist/associations/validation.d.ts +90 -0
  23. package/dist/associations/validation.d.ts.map +1 -0
  24. package/dist/associations/validation.js +339 -0
  25. package/dist/associations/validation.js.map +1 -0
  26. package/dist/attachment-records.d.ts +48 -0
  27. package/dist/attachment-records.d.ts.map +1 -0
  28. package/dist/attachment-records.js +52 -0
  29. package/dist/attachment-records.js.map +1 -0
  30. package/dist/collection.d.ts +182 -0
  31. package/dist/collection.d.ts.map +1 -0
  32. package/dist/collection.js +407 -0
  33. package/dist/collection.js.map +1 -0
  34. package/dist/content-match.d.ts +25 -0
  35. package/dist/content-match.d.ts.map +1 -0
  36. package/dist/content-match.js +51 -0
  37. package/dist/content-match.js.map +1 -0
  38. package/dist/content-translation.d.ts +42 -0
  39. package/dist/content-translation.d.ts.map +1 -0
  40. package/dist/content-translation.js +108 -0
  41. package/dist/content-translation.js.map +1 -0
  42. package/dist/did/did.d.ts.map +1 -0
  43. package/dist/{did.js → did/did.js} +3 -4
  44. package/dist/did/did.js.map +1 -0
  45. package/dist/{did-entry.d.ts → did/index.d.ts} +1 -1
  46. package/dist/did/index.d.ts.map +1 -0
  47. package/dist/{did-entry.js → did/index.js} +3 -3
  48. package/dist/did/index.js.map +1 -0
  49. package/dist/errors.d.ts +36 -63
  50. package/dist/errors.d.ts.map +1 -1
  51. package/dist/errors.js +35 -58
  52. package/dist/errors.js.map +1 -1
  53. package/dist/grants.d.ts +20 -43
  54. package/dist/grants.d.ts.map +1 -1
  55. package/dist/grants.js +71 -134
  56. package/dist/grants.js.map +1 -1
  57. package/dist/id.d.ts +13 -31
  58. package/dist/id.d.ts.map +1 -1
  59. package/dist/id.js +13 -31
  60. package/dist/id.js.map +1 -1
  61. package/dist/index.d.ts +14 -8
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +9 -5
  64. package/dist/index.js.map +1 -1
  65. package/dist/install.d.ts +141 -0
  66. package/dist/install.d.ts.map +1 -0
  67. package/dist/install.js +219 -0
  68. package/dist/install.js.map +1 -0
  69. package/dist/merge.d.ts.map +1 -1
  70. package/dist/merge.js +5 -11
  71. package/dist/merge.js.map +1 -1
  72. package/dist/migration-steps.d.ts +102 -0
  73. package/dist/migration-steps.d.ts.map +1 -0
  74. package/dist/migration-steps.js +293 -0
  75. package/dist/migration-steps.js.map +1 -0
  76. package/dist/query-validation.d.ts +28 -94
  77. package/dist/query-validation.d.ts.map +1 -1
  78. package/dist/query-validation.js +156 -336
  79. package/dist/query-validation.js.map +1 -1
  80. package/dist/record-changes.d.ts +2 -117
  81. package/dist/record-changes.d.ts.map +1 -1
  82. package/dist/record-changes.js +10 -212
  83. package/dist/record-changes.js.map +1 -1
  84. package/dist/schema.d.ts +18 -7
  85. package/dist/schema.d.ts.map +1 -1
  86. package/dist/schema.js +59 -30
  87. package/dist/schema.js.map +1 -1
  88. package/dist/scoped-stack/authority.d.ts +156 -0
  89. package/dist/scoped-stack/authority.d.ts.map +1 -0
  90. package/dist/scoped-stack/authority.js +384 -0
  91. package/dist/scoped-stack/authority.js.map +1 -0
  92. package/dist/scoped-stack/scoped-stack.d.ts +338 -0
  93. package/dist/scoped-stack/scoped-stack.d.ts.map +1 -0
  94. package/dist/scoped-stack/scoped-stack.js +776 -0
  95. package/dist/scoped-stack/scoped-stack.js.map +1 -0
  96. package/dist/scoped-stack/subscription.d.ts +55 -0
  97. package/dist/scoped-stack/subscription.d.ts.map +1 -0
  98. package/dist/scoped-stack/subscription.js +110 -0
  99. package/dist/scoped-stack/subscription.js.map +1 -0
  100. package/dist/stack/attachments.d.ts +24 -0
  101. package/dist/stack/attachments.d.ts.map +1 -0
  102. package/dist/stack/attachments.js +113 -0
  103. package/dist/stack/attachments.js.map +1 -0
  104. package/dist/{changes.d.ts → stack/changes.d.ts} +29 -65
  105. package/dist/stack/changes.d.ts.map +1 -0
  106. package/dist/{changes.js → stack/changes.js} +32 -66
  107. package/dist/stack/changes.js.map +1 -0
  108. package/dist/stack/client.d.ts +271 -0
  109. package/dist/stack/client.d.ts.map +1 -0
  110. package/dist/stack/client.js +9 -0
  111. package/dist/stack/client.js.map +1 -0
  112. package/dist/stack/identity-bindings.d.ts.map +1 -0
  113. package/dist/{identity-bindings.js → stack/identity-bindings.js} +8 -14
  114. package/dist/stack/identity-bindings.js.map +1 -0
  115. package/dist/stack/install-app.d.ts +22 -0
  116. package/dist/stack/install-app.d.ts.map +1 -0
  117. package/dist/stack/install-app.js +260 -0
  118. package/dist/stack/install-app.js.map +1 -0
  119. package/dist/stack/integrity.d.ts +94 -0
  120. package/dist/stack/integrity.d.ts.map +1 -0
  121. package/dist/stack/integrity.js +268 -0
  122. package/dist/stack/integrity.js.map +1 -0
  123. package/dist/{limits.d.ts → stack/limits.d.ts} +2 -5
  124. package/dist/stack/limits.d.ts.map +1 -0
  125. package/dist/{limits.js → stack/limits.js} +3 -6
  126. package/dist/stack/limits.js.map +1 -0
  127. package/dist/stack/migrations.d.ts +59 -0
  128. package/dist/stack/migrations.d.ts.map +1 -0
  129. package/dist/stack/migrations.js +141 -0
  130. package/dist/stack/migrations.js.map +1 -0
  131. package/dist/{stack-reads.d.ts → stack/reads.d.ts} +33 -6
  132. package/dist/stack/reads.d.ts.map +1 -0
  133. package/dist/{stack-reads.js → stack/reads.js} +49 -7
  134. package/dist/stack/reads.js.map +1 -0
  135. package/dist/stack/record-id.d.ts +35 -0
  136. package/dist/stack/record-id.d.ts.map +1 -0
  137. package/dist/stack/record-id.js +82 -0
  138. package/dist/stack/record-id.js.map +1 -0
  139. package/dist/stack/stack.d.ts +438 -0
  140. package/dist/stack/stack.d.ts.map +1 -0
  141. package/dist/stack/stack.js +1366 -0
  142. package/dist/stack/stack.js.map +1 -0
  143. package/dist/stack/system-types.d.ts +16 -0
  144. package/dist/stack/system-types.d.ts.map +1 -0
  145. package/dist/stack/system-types.js +111 -0
  146. package/dist/stack/system-types.js.map +1 -0
  147. package/dist/stack/type-grants.d.ts +20 -0
  148. package/dist/stack/type-grants.d.ts.map +1 -0
  149. package/dist/stack/type-grants.js +69 -0
  150. package/dist/stack/type-grants.js.map +1 -0
  151. package/dist/stack/write-expectation.d.ts +78 -0
  152. package/dist/stack/write-expectation.d.ts.map +1 -0
  153. package/dist/stack/write-expectation.js +71 -0
  154. package/dist/stack/write-expectation.js.map +1 -0
  155. package/dist/testing.d.ts +21 -26
  156. package/dist/testing.d.ts.map +1 -1
  157. package/dist/testing.js +50 -70
  158. package/dist/testing.js.map +1 -1
  159. package/dist/type-handle.d.ts +67 -78
  160. package/dist/type-handle.d.ts.map +1 -1
  161. package/dist/type-handle.js +44 -111
  162. package/dist/type-handle.js.map +1 -1
  163. package/dist/types/adapter.d.ts +223 -0
  164. package/dist/types/adapter.d.ts.map +1 -0
  165. package/dist/types/adapter.js +5 -0
  166. package/dist/types/adapter.js.map +1 -0
  167. package/dist/types/associations.d.ts +156 -0
  168. package/dist/types/associations.d.ts.map +1 -0
  169. package/dist/types/associations.js +13 -0
  170. package/dist/types/associations.js.map +1 -0
  171. package/dist/types/capabilities.d.ts +89 -0
  172. package/dist/types/capabilities.d.ts.map +1 -0
  173. package/dist/types/capabilities.js +5 -0
  174. package/dist/types/capabilities.js.map +1 -0
  175. package/dist/types/events.d.ts +155 -0
  176. package/dist/types/events.d.ts.map +1 -0
  177. package/dist/types/events.js +5 -0
  178. package/dist/types/events.js.map +1 -0
  179. package/dist/types/ids.d.ts +43 -0
  180. package/dist/types/ids.d.ts.map +1 -0
  181. package/dist/types/ids.js +5 -0
  182. package/dist/types/ids.js.map +1 -0
  183. package/dist/types/index.d.ts +19 -0
  184. package/dist/types/index.d.ts.map +1 -0
  185. package/dist/types/index.js +19 -0
  186. package/dist/types/index.js.map +1 -0
  187. package/dist/types/journal.d.ts +47 -0
  188. package/dist/types/journal.d.ts.map +1 -0
  189. package/dist/types/journal.js +5 -0
  190. package/dist/types/journal.js.map +1 -0
  191. package/dist/types/query.d.ts +185 -0
  192. package/dist/types/query.d.ts.map +1 -0
  193. package/dist/types/query.js +10 -0
  194. package/dist/types/query.js.map +1 -0
  195. package/dist/types/records.d.ts +76 -0
  196. package/dist/types/records.d.ts.map +1 -0
  197. package/dist/types/records.js +5 -0
  198. package/dist/types/records.js.map +1 -0
  199. package/dist/types/schema.d.ts +74 -0
  200. package/dist/types/schema.d.ts.map +1 -0
  201. package/dist/types/schema.js +5 -0
  202. package/dist/types/schema.js.map +1 -0
  203. package/dist/types/system.d.ts +161 -0
  204. package/dist/types/system.d.ts.map +1 -0
  205. package/dist/types/system.js +32 -0
  206. package/dist/types/system.js.map +1 -0
  207. package/dist/types/tokens.d.ts +39 -0
  208. package/dist/types/tokens.d.ts.map +1 -0
  209. package/dist/types/tokens.js +5 -0
  210. package/dist/types/tokens.js.map +1 -0
  211. package/dist/validate.d.ts +29 -70
  212. package/dist/validate.d.ts.map +1 -1
  213. package/dist/validate.js +65 -97
  214. package/dist/validate.js.map +1 -1
  215. package/dist/{attachment-download.d.ts → wire/attachment-download.d.ts} +0 -57
  216. package/dist/wire/attachment-download.d.ts.map +1 -0
  217. package/dist/{attachment-download.js → wire/attachment-download.js} +0 -61
  218. package/dist/wire/attachment-download.js.map +1 -0
  219. package/dist/{auth.d.ts → wire/auth.d.ts} +5 -8
  220. package/dist/wire/auth.d.ts.map +1 -0
  221. package/dist/{auth.js → wire/auth.js} +5 -8
  222. package/dist/wire/auth.js.map +1 -0
  223. package/dist/{wire-body.d.ts → wire/body.d.ts} +13 -5
  224. package/dist/wire/body.d.ts.map +1 -0
  225. package/dist/{wire-body.js → wire/body.js} +65 -7
  226. package/dist/wire/body.js.map +1 -0
  227. package/dist/{wire-entry.d.ts → wire/index.d.ts} +12 -12
  228. package/dist/wire/index.d.ts.map +1 -0
  229. package/dist/{wire-entry.js → wire/index.js} +13 -17
  230. package/dist/wire/index.js.map +1 -0
  231. package/dist/{wire-record.d.ts → wire/record.d.ts} +10 -22
  232. package/dist/wire/record.d.ts.map +1 -0
  233. package/dist/{wire-record.js → wire/record.js} +12 -24
  234. package/dist/wire/record.js.map +1 -0
  235. package/dist/{wire-request.d.ts → wire/request.d.ts} +20 -37
  236. package/dist/wire/request.d.ts.map +1 -0
  237. package/dist/{wire-request.js → wire/request.js} +79 -54
  238. package/dist/wire/request.js.map +1 -0
  239. package/package.json +7 -7
  240. package/dist/adapter-entry.d.ts.map +0 -1
  241. package/dist/adapter-entry.js.map +0 -1
  242. package/dist/attachment-download.d.ts.map +0 -1
  243. package/dist/attachment-download.js.map +0 -1
  244. package/dist/auth.d.ts.map +0 -1
  245. package/dist/auth.js.map +0 -1
  246. package/dist/changes.d.ts.map +0 -1
  247. package/dist/changes.js.map +0 -1
  248. package/dist/combine.d.ts.map +0 -1
  249. package/dist/combine.js.map +0 -1
  250. package/dist/did-entry.d.ts.map +0 -1
  251. package/dist/did-entry.js.map +0 -1
  252. package/dist/did.d.ts.map +0 -1
  253. package/dist/did.js.map +0 -1
  254. package/dist/identity-bindings.d.ts.map +0 -1
  255. package/dist/identity-bindings.js.map +0 -1
  256. package/dist/limits.d.ts.map +0 -1
  257. package/dist/limits.js.map +0 -1
  258. package/dist/record-id.d.ts +0 -70
  259. package/dist/record-id.d.ts.map +0 -1
  260. package/dist/record-id.js +0 -127
  261. package/dist/record-id.js.map +0 -1
  262. package/dist/scoped-stack.d.ts +0 -532
  263. package/dist/scoped-stack.d.ts.map +0 -1
  264. package/dist/scoped-stack.js +0 -1219
  265. package/dist/scoped-stack.js.map +0 -1
  266. package/dist/sort.d.ts.map +0 -1
  267. package/dist/sort.js.map +0 -1
  268. package/dist/stack-reads.d.ts.map +0 -1
  269. package/dist/stack-reads.js.map +0 -1
  270. package/dist/stack.d.ts +0 -971
  271. package/dist/stack.d.ts.map +0 -1
  272. package/dist/stack.js +0 -2012
  273. package/dist/stack.js.map +0 -1
  274. package/dist/types.d.ts +0 -1250
  275. package/dist/types.d.ts.map +0 -1
  276. package/dist/types.js +0 -49
  277. package/dist/types.js.map +0 -1
  278. package/dist/wire-body.d.ts.map +0 -1
  279. package/dist/wire-body.js.map +0 -1
  280. package/dist/wire-entry.d.ts.map +0 -1
  281. package/dist/wire-entry.js.map +0 -1
  282. package/dist/wire-record.d.ts.map +0 -1
  283. package/dist/wire-record.js.map +0 -1
  284. package/dist/wire-request.d.ts.map +0 -1
  285. package/dist/wire-request.js.map +0 -1
  286. /package/dist/{did.d.ts → did/did.d.ts} +0 -0
  287. /package/dist/{identity-bindings.d.ts → stack/identity-bindings.d.ts} +0 -0
@@ -2,130 +2,63 @@
2
2
  * Stack — Type handles
3
3
  * -------------------------------------------------------
4
4
  * A Type's schema written once as a literal, from which the compiler derives
5
- * the content type: `ContentOf` for a read or a create, `PatchOf` for a
6
- * `contentPatch`. A handle is a plain value, so `StackClient` code can use it
7
- * wherever it has no `defineType()` result.
5
+ * the content type: `ContentOf` for a create, `StoredContentOf` for a read.
6
+ * A handle is a plain value, so `StackClient`
7
+ * code can use it wherever it has no `defineType()` result.
8
8
  *
9
9
  * The derived types layer over runtime validation, which stays the guarantee.
10
- * What a typed read adds is a runtime check that the record is the handle's
11
- * Type. See docs/spec/data-model.md § Type handles.
10
+ * A handle reaches records through `client.collection(handle)`; see
11
+ * collection.ts and docs/spec/data-model.md § Type handles.
12
12
  */
13
- import { StackBadRequestError, StackValidationError } from './errors.js';
14
- import { parseTypeId } from './schema.js';
13
+ import { StackBadRequestError, StackMigrationError } from './errors.js';
14
+ import { lineageProblem, parseTypeId } from './schema.js';
15
+ import { applySteps, fieldOrigins, recordOrigins } from './migration-steps.js';
15
16
  /**
16
- * Name a Type and its schema in one literal. Pass the result to
17
- * `defineType({ ...handle, name })` and to the typed overloads of
18
- * `StackClient`. A handle names exactly one version: `Book.baseId` is the
19
- * argument a call about the whole family takes.
17
+ * Name a Type, its display name, its schema and the version it migrates
18
+ * from in one literal. Pass the result to `defineType()`, a manifest's
19
+ * `types` and `StackClient.collection()`. A handle names exactly
20
+ * one version: `Book.baseId` is the argument a call about the whole family
21
+ * takes.
20
22
  */
21
- export const typeHandle = (id, schema) => {
23
+ export const typeHandle = ({ id, name, schema, migratesFrom, }) => {
22
24
  const parsed = parseTypeId(id);
23
25
  if (!parsed) {
24
26
  throw new StackBadRequestError(`Invalid TypeId format: "${id}". Expected "namespace/name@version", e.g. "com.example.myapp/note@1".`);
25
27
  }
26
- return Object.freeze({ id, baseId: parsed.baseId, schema });
27
- };
28
- export const isTypeHandle = (value) => typeof value === 'object' &&
29
- value !== null &&
30
- typeof value.id === 'string' &&
31
- typeof value.baseId === 'string' &&
32
- typeof value.schema === 'object';
33
- // -------------------------------------------------------
34
- // Runtime narrowing
35
- // -------------------------------------------------------
36
- /**
37
- * Enum values the record holds that the handle's schema does not list. An
38
- * enum may gain values within a version, so a reader older than the writer
39
- * can meet one; throwing keeps the derived union exact.
40
- */
41
- const unknownEnumValues = (value, def, path, errors) => {
42
- if (value === undefined || value === null)
43
- return;
44
- if (def.kind === 'string') {
45
- if (def.enum && typeof value === 'string' && !def.enum.includes(value)) {
46
- errors.push({
47
- path,
48
- message: `Expected one of ${def.enum.map((v) => JSON.stringify(v)).join(', ')}, got ${JSON.stringify(value)}`,
49
- });
50
- }
51
- return;
52
- }
53
- if (def.kind === 'array' && !def.open && Array.isArray(value)) {
54
- value.forEach((item, i) => unknownEnumValues(item, def.items, `${path}[${i}]`, errors));
55
- return;
56
- }
57
- if (def.kind === 'object' && !def.open && typeof value === 'object' && !Array.isArray(value)) {
58
- walkEnums(value, def.properties, path, errors);
59
- }
60
- };
61
- const walkEnums = (content, schema, prefix, errors) => {
62
- for (const key of Object.keys(schema)) {
63
- unknownEnumValues(content[key], schema[key], prefix ? `${prefix}.${key}` : key, errors);
64
- }
28
+ const from = typeof migratesFrom === 'object' && migratesFrom !== null ? migratesFrom.id : migratesFrom;
29
+ const problem = lineageProblem(id, from);
30
+ if (problem)
31
+ throw new StackBadRequestError(problem);
32
+ return Object.freeze({
33
+ id,
34
+ baseId: parsed.baseId,
35
+ name,
36
+ schema,
37
+ ...(from !== undefined && { migratesFrom: from }),
38
+ });
65
39
  };
66
40
  /**
67
- * Narrow a record to a handle's content type: it must be exactly the
68
- * handle's Type, and every enum field must hold a value the handle lists.
69
- * A record of another Type throws, and so does one whose family has moved
70
- * past the handle's version.
41
+ * Build the migration from `from` to `to` out of declared steps, checked
42
+ * against both schemas here so a step the target would refuse fails before
43
+ * any record is written. Within a family, `to` must name `from` as its
44
+ * `migratesFrom`. See docs/spec/data-model.md § Migration steps.
71
45
  */
72
- export const narrowRecord = (handle, record) => {
73
- if (record.typeId !== handle.id) {
74
- throw new StackBadRequestError(`Record "${record.id}" is ${record.typeId}, not ${handle.id}`);
46
+ export const migration = (from, to, steps) => {
47
+ const refuse = (problem) => new StackMigrationError(`Cannot migrate "${from.id}" to "${to.id}": ${problem}.`);
48
+ if (to.baseId === from.baseId && to.migratesFrom !== from.id) {
49
+ throw refuse(`"${to.id}" migrates from ${to.migratesFrom ? `"${to.migratesFrom}"` : 'nothing'}`);
75
50
  }
76
- const errors = [];
77
- walkEnums(record.content, handle.schema, '', errors);
78
- if (errors.length > 0)
79
- throw new StackValidationError(errors);
80
- return record;
81
- };
82
- /** The ways a typed read can be asked to see a tombstone. */
83
- export const assertLiveFilter = (filter) => {
84
- if (filter?.includeDeleted) {
85
- throw new StackBadRequestError('A typed read sees live records only; use the untyped read to include soft-deleted records.');
86
- }
87
- };
88
- export const typedGet = async (client, handle, id) => {
89
- const record = await client.get(id, { presentAt: 'latest' });
90
- return record && narrowRecord(handle, record);
91
- };
92
- export const typedQuery = async (client, handle, query = {}) => {
93
- assertLiveFilter(query.filter);
94
- // The family, not the handle's version: a record still at an older
95
- // version must be migrated up, or refused as stale, never skipped.
96
- const result = await client.query({
97
- ...query,
98
- filter: { ...query.filter, baseId: handle.baseId },
99
- presentAt: 'latest',
51
+ const frozen = Object.freeze([...steps]);
52
+ const origins = fieldOrigins(frozen, from.schema, to.schema);
53
+ if (typeof origins === 'string')
54
+ throw refuse(origins);
55
+ const built = Object.freeze({
56
+ from: from.id,
57
+ to: to.id,
58
+ steps: frozen,
59
+ migrate: (content) => applySteps(frozen, content),
100
60
  });
101
- return { ...result, records: result.records.map((r) => narrowRecord(handle, r)) };
61
+ recordOrigins(built, origins);
62
+ return built;
102
63
  };
103
- export const typedCreate = async (client, handle, content, opts) => client.create(handle.id, content, opts);
104
- export const typedMutate = async (client, handle, id, changes, opts) => {
105
- // A patch is validated against the record's own stored Type, so one made
106
- // through a handle for another version would be checked by a schema it
107
- // was not written for. A missing, unreadable or deleted record is left to
108
- // mutate(), which refuses it in its own words.
109
- const current = await client.get(id, { includeDeleted: true });
110
- if (current && current.typeId !== handle.id) {
111
- throw new StackBadRequestError(`Record "${id}" is ${current.typeId}, not ${handle.id}`);
112
- }
113
- return narrowRecord(handle, await client.mutate(id, changes, opts));
114
- };
115
- export const typedSubscribe = (client, handle, handler, opts = {}) =>
116
- // Exactly the handle's version: an event carries its record as stored, so
117
- // a subscription cannot migrate it the way a typed read does, and a
118
- // record of another version has no honest typing here.
119
- client.subscribe((change) => {
120
- const { record, ...rest } = change;
121
- let narrowed;
122
- try {
123
- narrowed = record && narrowRecord(handle, record);
124
- }
125
- catch (err) {
126
- if (!(err instanceof StackValidationError))
127
- throw err;
128
- }
129
- handler(narrowed ? { ...rest, record: narrowed } : rest);
130
- }, { ...opts, filter: { ...opts.filter, typeId: handle.id } });
131
64
  //# sourceMappingURL=type-handle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"type-handle.js","sourceRoot":"","sources":["../src/type-handle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"type-handle.js","sourceRoot":"","sources":["../src/type-handle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AA4H/E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAqC,EAC7D,EAAE,EACF,IAAI,EACJ,MAAM,EACN,YAAY,GAMb,EAAiB,EAAE;IAClB,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,oBAAoB,CAC5B,2BAA2B,EAAE,wEAAwE,CACtG,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GACR,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;IAC7F,MAAM,OAAO,GAAG,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACzC,IAAI,OAAO;QAAE,MAAM,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,EAAE;QACF,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,IAAI;QACJ,MAAM;QACN,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;KAClD,CAAC,CAAC;AACL,CAAC,CAAC;AAoBF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,IAAmB,EACnB,EAAiB,EACjB,KAA4D,EACT,EAAE;IACrD,MAAM,MAAM,GAAG,CAAC,OAAe,EAAE,EAAE,CACjC,IAAI,mBAAmB,CAAC,mBAAmB,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,OAAO,GAAG,CAAC,CAAC;IACpF,IAAI,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,YAAY,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;QAC7D,MAAM,MAAM,CACV,IAAI,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CACnF,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,CAA6B,CAAC;IACrE,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAC7D,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;QAC1B,IAAI,EAAE,IAAI,CAAC,EAAE;QACb,EAAE,EAAE,EAAE,CAAC,EAAE;QACT,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,CAAC,OAAgC,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC;KAC3E,CAAiE,CAAC;IACnE,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,KAAK,CAAC;AACf,CAAC,CAAC"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * The storage adapter interfaces and the per-call options Stack hands them.
3
+ */
4
+ import type { AssociationEdit, RecordChangeSet } from './associations.js';
5
+ import type { StackCapabilities } from './capabilities.js';
6
+ import type { RecordChange, Unsubscribe, SubscribeOptions } from './events.js';
7
+ import type { RecordId, TypeId, FileId, AppId, EntityId, Actor } from './ids.js';
8
+ import type { JournalEntryInput, RecordJournalEntry, JournalQuery } from './journal.js';
9
+ import type { StackQuery, QueryResult } from './query.js';
10
+ import type { StackRecord, RecordVersion, VersionsQuery } from './records.js';
11
+ import type { StackType } from './schema.js';
12
+ /**
13
+ * Opt-in optimistic-concurrency precondition. On mismatch the mutation
14
+ * throws StackVersionConflictError and changes nothing; an adapter checks
15
+ * it atomically inside its write. See docs/spec/versioning.md § Optimistic
16
+ * concurrency (`ifVersion`).
17
+ */
18
+ export type IfVersionOptions = {
19
+ ifVersion?: number;
20
+ };
21
+ /**
22
+ * Accepted by every mutating StackRecordAdapter method. The adapter
23
+ * persists this prior-state snapshot as part of the SAME atomic write as
24
+ * the mutation, so a crash between the two can't leave an orphan versions
25
+ * row. Server-backed adapters (already atomic per-request) can ignore it.
26
+ */
27
+ export type SnapshotOptions = {
28
+ snapshot?: RecordVersion;
29
+ };
30
+ /**
31
+ * Whether a mutateRecord() call advances `version`/`updatedAt`. `Stack`
32
+ * computes it from what the change set moves; absent means `true`.
33
+ * See docs/spec/versioning.md § Version history.
34
+ */
35
+ export type BumpVersionOptions = {
36
+ bumpsVersion?: boolean;
37
+ };
38
+ /**
39
+ * Who is performing a mutation, stamped onto the record in the same write.
40
+ * `ScopedStack` supplies it from the request's identities; a caller of
41
+ * plain `Stack` supplies it only when reconstructing an attributed write.
42
+ * See docs/spec/data-model.md § Authorship and attribution.
43
+ */
44
+ export type ActorOptions = {
45
+ actor?: Actor;
46
+ };
47
+ /**
48
+ * Accepted by every mutating StackRecordAdapter method. The adapter
49
+ * appends the entry, allocating its `seq`, inside the SAME write as the
50
+ * mutation, so a crash cannot leave a change unjournaled.
51
+ */
52
+ export type JournalOptions = {
53
+ journal?: JournalEntryInput;
54
+ };
55
+ /**
56
+ * What every mutating StackRecordAdapter method that bumps `version` takes.
57
+ * mutateRecord() adds BumpVersionOptions and deleteRecord() adds `purge`.
58
+ */
59
+ export type MutateOptions = IfVersionOptions & SnapshotOptions & ActorOptions & JournalOptions;
60
+ /** The metadata an upload's `_attachment@1` record carries beside its bytes. */
61
+ export type PutAttachmentOptions = {
62
+ mimeType: string;
63
+ filename?: string;
64
+ /** Attribution for the metadata record, as create()'s `appId`. */
65
+ appId?: AppId;
66
+ };
67
+ /**
68
+ * The record-storage half of an adapter: structured data, queries,
69
+ * associations, versioning, type definitions, and stack identity.
70
+ */
71
+ export interface StackRecordAdapter {
72
+ readonly capabilities: StackCapabilities;
73
+ /** DID of the stack owner. Set during adapter initialization. */
74
+ readonly ownerEntityId: EntityId;
75
+ /**
76
+ * IANA timezone string for this stack, or undefined if never set.
77
+ * Passthrough app metadata with no default — see docs/spec.md § The
78
+ * `_config` record.
79
+ */
80
+ readonly timezone: string | undefined;
81
+ /**
82
+ * Throws StackConflictError if `record.id` already exists — never a
83
+ * silent overwrite. The check must be atomic with the write (a PK/unique
84
+ * constraint or equivalent); Stack itself doesn't pre-check, so a raw
85
+ * adapter that skips this enforces nothing.
86
+ */
87
+ createRecord(record: StackRecord, opts?: JournalOptions): Promise<StackRecord>;
88
+ getRecord(id: RecordId): Promise<StackRecord | null>;
89
+ /**
90
+ * Apply a change set in one write — the only multi-aspect atomic write a
91
+ * record has, so a publish cannot half-land. Never touches `typeId`; see
92
+ * commitMigration(). `Stack` validates it and computes `bumpsVersion`,
93
+ * and never hands an adapter a change set that changes nothing.
94
+ * See docs/spec/data-model.md § Mutations.
95
+ */
96
+ mutateRecord(id: RecordId, changes: RecordChangeSet, opts?: MutateOptions & BumpVersionOptions): Promise<StackRecord>;
97
+ /**
98
+ * Returns the record this call acted on: as it now stands after a soft
99
+ * delete, and as it stood immediately before destruction after a
100
+ * purge — captured inside the same write, so nothing can observe or alter
101
+ * it in between. Null when there was no record to delete, which is the
102
+ * only case that mutates nothing.
103
+ */
104
+ deleteRecord(id: RecordId, opts?: {
105
+ purge?: boolean;
106
+ } & MutateOptions): Promise<StackRecord | null>;
107
+ /** Reverse a soft delete. Returns the record as it now stands. */
108
+ undeleteRecord(id: RecordId, opts?: MutateOptions): Promise<StackRecord>;
109
+ /**
110
+ * `query.sort`, when present, always carries a `direction`: `Stack`
111
+ * resolves the defaults before any adapter sees the query.
112
+ */
113
+ queryRecords(query: StackQuery): Promise<QueryResult>;
114
+ /**
115
+ * Apply a list of adds and removes as one write, all or none, removes
116
+ * before adds. Never bumps `version`/`updatedAt` and never snapshots — a
117
+ * set-add composes regardless of write order. A list mixing authority
118
+ * and data elements is refused.
119
+ * See docs/spec/adapters.md § Amending associations.
120
+ */
121
+ amendAssociations(id: RecordId, changes: AssociationEdit[], opts?: JournalOptions): Promise<StackRecord>;
122
+ /**
123
+ * Snapshots newest first; omitting `query` reads every version.
124
+ * See docs/spec/versioning.md § Version history.
125
+ */
126
+ getVersions(id: RecordId, query?: VersionsQuery): Promise<RecordVersion[]>;
127
+ getVersion(id: RecordId, version: number): Promise<RecordVersion | null>;
128
+ /**
129
+ * Standalone snapshot write, outside of a mutation's own atomic path.
130
+ * Mutating methods above take a `snapshot` option instead, so the
131
+ * snapshot and the mutation land in one write — see SnapshotOptions.
132
+ */
133
+ saveVersion(id: RecordId, version: RecordVersion): Promise<void>;
134
+ /**
135
+ * Read a record's change journal, oldest first — required, on the same
136
+ * footing as getVersions(). A recovery mechanism an app cannot rely on is
137
+ * most of the way to no mechanism at all, so an adapter with no journal
138
+ * refuses the call rather than declining to have the method.
139
+ * See docs/spec/journal.md § Reading it.
140
+ */
141
+ getJournal(id: RecordId, query?: JournalQuery): Promise<RecordJournalEntry[]>;
142
+ /**
143
+ * Restore a record to a previous version's `content` and `typeId` —
144
+ * everything a snapshot carries. Containment, listing and associations
145
+ * are left where they stand, there being nothing to restore them *from*.
146
+ * Bumps version internally; throws StackNotFoundError if the version
147
+ * doesn't exist.
148
+ */
149
+ restoreVersion(id: RecordId, version: number, opts?: MutateOptions): Promise<StackRecord>;
150
+ /**
151
+ * Commit a migration: write new content under a new typeId in one step.
152
+ * This is the only way a record's typeId changes after creation — used by
153
+ * Stack.commitMigration() and Stack.migrateAll(); Stack.mutate() never
154
+ * changes typeId as a side effect. Bumps version internally.
155
+ */
156
+ commitMigration(id: RecordId, toTypeId: TypeId, content: Record<string, unknown>, opts?: MutateOptions): Promise<StackRecord>;
157
+ saveType(type: StackType): Promise<void>;
158
+ getType(id: TypeId): Promise<StackType | null>;
159
+ listTypes(): Promise<StackType[]>;
160
+ /**
161
+ * Atomically verify fileId is unreferenced and purge its metadata
162
+ * records, returning them; StackConflictError if still referenced.
163
+ * Optional — Stack.deleteAttachment() has a non-atomic fallback.
164
+ * `metadataTypeIds` is the resolved `_attachment` family, so an adapter
165
+ * needs no baseId concept. See docs/spec/attachments.md § Deleting attachments.
166
+ */
167
+ deleteUnreferencedAttachmentRecords?(fileId: FileId, metadataTypeIds: TypeId[]): Promise<StackRecord[]>;
168
+ /**
169
+ * Relay changes that originated elsewhere — the inverse direction from
170
+ * `Stack`, which emits every change made through it. Optional, and
171
+ * absent on every local adapter: exactly one process owns a stack's
172
+ * storage, so locally there is no third party whose writes could have
173
+ * been missed. See docs/spec/events.md § Where events come from.
174
+ */
175
+ subscribeChanges?(opts: SubscribeOptions, handler: (change: RecordChange) => void): Promise<Unsubscribe>;
176
+ flush?(): Promise<void>;
177
+ close?(): Promise<void>;
178
+ }
179
+ /** One stored blob, as reported by StackBlobAdapter.listBlobs(). */
180
+ export type BlobInfo = {
181
+ fileId: FileId;
182
+ size: number;
183
+ /** When the blob was written. Used to apply a GC grace period to fresh, not-yet-associated uploads. */
184
+ modifiedAt: Date;
185
+ };
186
+ /**
187
+ * The blob-storage half of an adapter. Handles raw binary data only;
188
+ * attachment metadata lives on _attachment@1 records in the record adapter.
189
+ */
190
+ export interface StackBlobAdapter {
191
+ putBlob(data: Uint8Array): Promise<FileId>;
192
+ /**
193
+ * Returns a plain `Uint8Array` (never a subclass such as `Buffer`) that the
194
+ * caller owns: changing it never changes the stored bytes.
195
+ */
196
+ getBlob(fileId: FileId): Promise<Uint8Array>;
197
+ deleteBlob(fileId: FileId): Promise<void>;
198
+ /**
199
+ * Enumerate every blob currently in storage. Optional — without it,
200
+ * garbage collection can't find bare-bytes orphans (bytes with no
201
+ * metadata record at all). See docs/spec/attachments.md § Garbage
202
+ * collection.
203
+ */
204
+ listBlobs?(): Promise<BlobInfo[]>;
205
+ flush?(): Promise<void>;
206
+ close?(): Promise<void>;
207
+ }
208
+ /**
209
+ * A complete adapter: record storage and blob storage combined.
210
+ * Pass this to Stack.open(). Build one with combineAdapters() when you
211
+ * want different backends for records and blobs (e.g. SQLite + S3).
212
+ */
213
+ export type StackAdapter = StackRecordAdapter & StackBlobAdapter & {
214
+ /**
215
+ * Store bytes and create the accompanying _attachment@1 record as one
216
+ * atomic operation. Optional; implement only when bytes and records
217
+ * live behind a single boundary (today: APIAdapter alone), and never
218
+ * synthesized by combineAdapters(). A security boundary, not an
219
+ * efficiency shortcut — see docs/spec/adapters.md § Interface split.
220
+ */
221
+ putAttachmentWithMetadata?(data: Uint8Array, opts: PutAttachmentOptions): Promise<StackRecord>;
222
+ };
223
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/types/adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG,eAAe,GAAG,YAAY,GAAG,cAAc,CAAC;AAE/F,gFAAgF;AAChF,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC;IAEzC,iEAAiE;IACjE,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAGtC;;;;;OAKG;IACH,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/E,SAAS,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACrD;;;;;;OAMG;IACH,YAAY,CACV,EAAE,EAAE,QAAQ,EACZ,OAAO,EAAE,eAAe,EACxB,IAAI,CAAC,EAAE,aAAa,GAAG,kBAAkB,GACxC,OAAO,CAAC,WAAW,CAAC,CAAC;IACxB;;;;;;OAMG;IACH,YAAY,CACV,EAAE,EAAE,QAAQ,EACZ,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,aAAa,GACzC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC/B,kEAAkE;IAClE,cAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACzE;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAGtD;;;;;;OAMG;IACH,iBAAiB,CACf,EAAE,EAAE,QAAQ,EACZ,OAAO,EAAE,eAAe,EAAE,EAC1B,IAAI,CAAC,EAAE,cAAc,GACpB,OAAO,CAAC,WAAW,CAAC,CAAC;IAGxB;;;OAGG;IACH,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAC3E,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IACzE;;;;OAIG;IACH,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC9E;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAE1F;;;;;OAKG;IACH,eAAe,CACb,EAAE,EAAE,QAAQ,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAAC,WAAW,CAAC,CAAC;IAGxB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC/C,SAAS,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAElC;;;;;;OAMG;IACH,mCAAmC,CAAC,CAClC,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,EAAE,GACxB,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAE1B;;;;;;OAMG;IACH,gBAAgB,CAAC,CACf,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GACtC,OAAO,CAAC,WAAW,CAAC,CAAC;IAGxB,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,oEAAoE;AACpE,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,uGAAuG;IACvG,UAAU,EAAE,IAAI,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAE/B,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1C;;;;;OAKG;IACH,SAAS,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAGlC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAC3C,gBAAgB,GAAG;IACjB;;;;;;OAMG;IACH,yBAAyB,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAChG,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * The storage adapter interfaces and the per-call options Stack hands them.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/types/adapter.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Associations: the edges a Record carries, authority and data alike,
3
+ * and the change shapes that move them.
4
+ */
5
+ import type { RecordId, FileId, EntityId } from './ids.js';
6
+ export type TagAssociation = {
7
+ kind: 'tag';
8
+ label: string;
9
+ };
10
+ /**
11
+ * `attachmentRecordId` names the `_attachment` record whose upload
12
+ * established this reference — annotation, not identity, since `fileId`
13
+ * alone is what GC, the `referencesFileId` filter and file access ask
14
+ * about. See docs/spec/attachments.md § Naming the upload a reference came from.
15
+ */
16
+ export type AttachmentAssociation = {
17
+ kind: 'attachment';
18
+ label: string;
19
+ fileId: FileId;
20
+ attachmentRecordId?: RecordId;
21
+ };
22
+ /**
23
+ * A Record in this stack, or in another one. `stackUrl` is what makes a
24
+ * RecordId meaningful outside the stack that minted it — absent means this
25
+ * stack. See docs/spec/data-model.md § Associations.
26
+ */
27
+ export type RecordTarget = {
28
+ kind: 'record';
29
+ recordId: RecordId;
30
+ stackUrl?: string;
31
+ };
32
+ /**
33
+ * A "who" — a DID, which means the same thing in every stack. Group
34
+ * rosters are the canonical use: membership names identities, not records.
35
+ * See docs/spec/identity.md § Group.
36
+ */
37
+ export type EntityTarget = {
38
+ kind: 'entity';
39
+ entityId: EntityId;
40
+ };
41
+ /**
42
+ * Something outside the stack entirely. `ns` names the scheme that
43
+ * interprets `id` — e.g. "atproto", "activitypub", "email", "url" — so an
44
+ * app selects on it rather than sniffing the identifier.
45
+ * See docs/spec/data-model.md § Relationship targets.
46
+ */
47
+ export type ExternalTarget = {
48
+ kind: 'external';
49
+ ns: string;
50
+ id: string;
51
+ };
52
+ /** What a relationship association points at. */
53
+ export type RelationshipTarget = RecordTarget | EntityTarget | ExternalTarget;
54
+ export type RelationshipAssociation = {
55
+ kind: 'relationship';
56
+ label: string;
57
+ target: RelationshipTarget;
58
+ };
59
+ /**
60
+ * A grant of access to the Record carrying it. The bit is the label, so
61
+ * granting and revoking are a plain add and remove and the element's
62
+ * identity carries its whole meaning. Its grantee shape is its own rather
63
+ * than a `RelationshipTarget`: a target names no role and has no group
64
+ * arm. See docs/spec/access-control.md § Record-level permissions.
65
+ */
66
+ export type PermissionAssociation = {
67
+ kind: 'permission';
68
+ label: 'read' | 'write';
69
+ grantee: Grantee;
70
+ };
71
+ /** An entity's standing within a `_group` Record's roster. `admin` implies `member` for ACL purposes. */
72
+ export type GroupRole = 'member' | 'admin';
73
+ /**
74
+ * The grantee arms both permission layers share, spelled identically so a
75
+ * value built for one is valid for the other. `role` is required — `member`
76
+ * is the wider set, `admin` the narrower, matching the roster labels where
77
+ * admin implies member. See docs/spec/access-control.md § Who a grant reaches.
78
+ */
79
+ export type Grantee = {
80
+ kind: 'entity';
81
+ entityId: EntityId;
82
+ } | {
83
+ kind: 'group';
84
+ groupId: RecordId;
85
+ role: GroupRole;
86
+ };
87
+ /**
88
+ * Reach to the world, spelled affirmatively: it names no grantee and
89
+ * carries no bit beyond `read`, so no dropped field on a
90
+ * `PermissionAssociation` can produce it.
91
+ * See docs/spec/access-control.md § Record-level permissions.
92
+ */
93
+ export type AnyoneAssociation = {
94
+ kind: 'anyone';
95
+ label: 'read';
96
+ };
97
+ /**
98
+ * The authority half of the association table — what the `permissions`
99
+ * field projects. See docs/spec/access-control.md § Record-level
100
+ * permissions.
101
+ */
102
+ export type AuthorityAssociation = PermissionAssociation | AnyoneAssociation;
103
+ /**
104
+ * The data half — what the `associations` field projects, and the only
105
+ * kinds `associate()`/`dissociate()` accept.
106
+ * See docs/spec/data-model.md § Associations.
107
+ */
108
+ export type DataAssociation = TagAssociation | AttachmentAssociation | RelationshipAssociation;
109
+ /**
110
+ * Every edge a Record carries, authority and data alike. One shape, one
111
+ * delta and one durability tier; the two halves stay separate call
112
+ * surfaces because they carry different authority.
113
+ * See docs/spec/access-control.md § Record-level permissions.
114
+ */
115
+ export type Association = DataAssociation | AuthorityAssociation;
116
+ /**
117
+ * One association a write moved, and what it moved from. Each inverse is
118
+ * local to one element, so there is no join key to get wrong; `previous`
119
+ * is carried in full, which is what makes a `repoint` undoable.
120
+ * See docs/spec/journal.md § The entry.
121
+ */
122
+ export type AssociationChange = {
123
+ op: 'add';
124
+ association: Association;
125
+ } | {
126
+ op: 'repoint';
127
+ association: Association;
128
+ previous: Association;
129
+ } | {
130
+ op: 'remove';
131
+ association: Association;
132
+ };
133
+ /**
134
+ * What a caller sends: the journal's shape without `repoint`, which the
135
+ * journal records and no caller requests. See docs/spec/journal.md § The entry.
136
+ */
137
+ export type AssociationEdit = Exclude<AssociationChange, {
138
+ op: 'repoint';
139
+ }>;
140
+ /**
141
+ * The aspects of an existing record one mutate() call may move, in any
142
+ * combination. Keys are read for presence: `unlisted: false` is a change,
143
+ * an omitted key is untouched. Each key replaces its aspect whole except
144
+ * `contentPatch`, which merges at the top level (`null` removes).
145
+ * See docs/spec/data-model.md § Mutations.
146
+ */
147
+ export type RecordChangeSet = {
148
+ contentPatch?: Record<string, unknown | null>;
149
+ parentId?: RecordId | null;
150
+ permissions?: AuthorityAssociation[];
151
+ associations?: DataAssociation[];
152
+ unlisted?: boolean;
153
+ };
154
+ /** The keys of a change set, for presence checks that must not miss one. */
155
+ export declare const RECORD_CHANGE_SET_KEYS: readonly ["contentPatch", "parentId", "permissions", "associations", "unlisted"];
156
+ //# sourceMappingURL=associations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"associations.d.ts","sourceRoot":"","sources":["../../src/types/associations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Associations: the edges a Record carries, authority and data alike,
3
+ * and the change shapes that move them.
4
+ */
5
+ /** The keys of a change set, for presence checks that must not miss one. */
6
+ export const RECORD_CHANGE_SET_KEYS = [
7
+ 'contentPatch',
8
+ 'parentId',
9
+ 'permissions',
10
+ 'associations',
11
+ 'unlisted',
12
+ ];
13
+ //# sourceMappingURL=associations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"associations.js","sourceRoot":"","sources":["../../src/types/associations.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2JH,4EAA4E;AAC5E,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,cAAc;IACd,UAAU;IACV,aAAa;IACb,cAAc;IACd,UAAU;CAC2C,CAAC"}