@haverstack/core 0.41.0 → 0.43.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 (317) hide show
  1. package/README.md +124 -64
  2. package/dist/access.d.ts +43 -47
  3. package/dist/access.d.ts.map +1 -1
  4. package/dist/access.js +66 -101
  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} +18 -3
  9. package/dist/adapter/combine.js.map +1 -0
  10. package/dist/adapter/index.d.ts +19 -0
  11. package/dist/adapter/index.d.ts.map +1 -0
  12. package/dist/adapter/index.js +16 -0
  13. package/dist/adapter/index.js.map +1 -0
  14. package/dist/adapter/reach.d.ts +14 -0
  15. package/dist/adapter/reach.d.ts.map +1 -0
  16. package/dist/adapter/reach.js +31 -0
  17. package/dist/adapter/reach.js.map +1 -0
  18. package/dist/{sort.d.ts → adapter/sort.d.ts} +20 -20
  19. package/dist/adapter/sort.d.ts.map +1 -0
  20. package/dist/{sort.js → adapter/sort.js} +37 -27
  21. package/dist/adapter/sort.js.map +1 -0
  22. package/dist/associations/identity.d.ts +69 -0
  23. package/dist/associations/identity.d.ts.map +1 -0
  24. package/dist/associations/identity.js +174 -0
  25. package/dist/associations/identity.js.map +1 -0
  26. package/dist/associations/validation.d.ts +83 -0
  27. package/dist/associations/validation.d.ts.map +1 -0
  28. package/dist/associations/validation.js +312 -0
  29. package/dist/associations/validation.js.map +1 -0
  30. package/dist/attachment-records.d.ts +48 -0
  31. package/dist/attachment-records.d.ts.map +1 -0
  32. package/dist/attachment-records.js +52 -0
  33. package/dist/attachment-records.js.map +1 -0
  34. package/dist/collection.d.ts +178 -0
  35. package/dist/collection.d.ts.map +1 -0
  36. package/dist/collection.js +397 -0
  37. package/dist/collection.js.map +1 -0
  38. package/dist/content-match.d.ts +25 -0
  39. package/dist/content-match.d.ts.map +1 -0
  40. package/dist/content-match.js +51 -0
  41. package/dist/content-match.js.map +1 -0
  42. package/dist/content-translation.d.ts +42 -0
  43. package/dist/content-translation.d.ts.map +1 -0
  44. package/dist/content-translation.js +108 -0
  45. package/dist/content-translation.js.map +1 -0
  46. package/dist/did/did.d.ts.map +1 -0
  47. package/dist/{did.js → did/did.js} +3 -4
  48. package/dist/did/did.js.map +1 -0
  49. package/dist/{did-entry.d.ts → did/index.d.ts} +1 -1
  50. package/dist/did/index.d.ts.map +1 -0
  51. package/dist/{did-entry.js → did/index.js} +3 -3
  52. package/dist/did/index.js.map +1 -0
  53. package/dist/errors.d.ts +54 -66
  54. package/dist/errors.d.ts.map +1 -1
  55. package/dist/errors.js +58 -62
  56. package/dist/errors.js.map +1 -1
  57. package/dist/grants.d.ts +20 -44
  58. package/dist/grants.d.ts.map +1 -1
  59. package/dist/grants.js +69 -151
  60. package/dist/grants.js.map +1 -1
  61. package/dist/id.d.ts +13 -31
  62. package/dist/id.d.ts.map +1 -1
  63. package/dist/id.js +13 -31
  64. package/dist/id.js.map +1 -1
  65. package/dist/index.d.ts +13 -9
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +9 -6
  68. package/dist/index.js.map +1 -1
  69. package/dist/install.d.ts +3 -6
  70. package/dist/install.d.ts.map +1 -1
  71. package/dist/install.js +6 -10
  72. package/dist/install.js.map +1 -1
  73. package/dist/lazy.d.ts +13 -0
  74. package/dist/lazy.d.ts.map +1 -0
  75. package/dist/lazy.js +27 -0
  76. package/dist/lazy.js.map +1 -0
  77. package/dist/merge.d.ts +1 -1
  78. package/dist/merge.d.ts.map +1 -1
  79. package/dist/merge.js +6 -12
  80. package/dist/merge.js.map +1 -1
  81. package/dist/migration-steps.d.ts +102 -0
  82. package/dist/migration-steps.d.ts.map +1 -0
  83. package/dist/migration-steps.js +293 -0
  84. package/dist/migration-steps.js.map +1 -0
  85. package/dist/query-validation.d.ts +68 -121
  86. package/dist/query-validation.d.ts.map +1 -1
  87. package/dist/query-validation.js +214 -380
  88. package/dist/query-validation.js.map +1 -1
  89. package/dist/record-changes.d.ts +11 -150
  90. package/dist/record-changes.d.ts.map +1 -1
  91. package/dist/record-changes.js +14 -305
  92. package/dist/record-changes.js.map +1 -1
  93. package/dist/schema.d.ts +18 -7
  94. package/dist/schema.d.ts.map +1 -1
  95. package/dist/schema.js +59 -30
  96. package/dist/schema.js.map +1 -1
  97. package/dist/scoped-stack/authority-snapshot.d.ts +37 -0
  98. package/dist/scoped-stack/authority-snapshot.d.ts.map +1 -0
  99. package/dist/scoped-stack/authority-snapshot.js +49 -0
  100. package/dist/scoped-stack/authority-snapshot.js.map +1 -0
  101. package/dist/scoped-stack/authority.d.ts +169 -0
  102. package/dist/scoped-stack/authority.d.ts.map +1 -0
  103. package/dist/scoped-stack/authority.js +408 -0
  104. package/dist/scoped-stack/authority.js.map +1 -0
  105. package/dist/scoped-stack/family-policy.d.ts +59 -0
  106. package/dist/scoped-stack/family-policy.d.ts.map +1 -0
  107. package/dist/scoped-stack/family-policy.js +68 -0
  108. package/dist/scoped-stack/family-policy.js.map +1 -0
  109. package/dist/scoped-stack/scoped-stack.d.ts +318 -0
  110. package/dist/scoped-stack/scoped-stack.d.ts.map +1 -0
  111. package/dist/scoped-stack/scoped-stack.js +695 -0
  112. package/dist/scoped-stack/scoped-stack.js.map +1 -0
  113. package/dist/scoped-stack/subscription.d.ts +36 -0
  114. package/dist/scoped-stack/subscription.d.ts.map +1 -0
  115. package/dist/scoped-stack/subscription.js +69 -0
  116. package/dist/scoped-stack/subscription.js.map +1 -0
  117. package/dist/stack/arguments.d.ts +27 -0
  118. package/dist/stack/arguments.d.ts.map +1 -0
  119. package/dist/stack/arguments.js +53 -0
  120. package/dist/stack/arguments.js.map +1 -0
  121. package/dist/stack/attachments.d.ts +24 -0
  122. package/dist/stack/attachments.d.ts.map +1 -0
  123. package/dist/stack/attachments.js +113 -0
  124. package/dist/stack/attachments.js.map +1 -0
  125. package/dist/{changes.d.ts → stack/changes.d.ts} +30 -72
  126. package/dist/stack/changes.d.ts.map +1 -0
  127. package/dist/{changes.js → stack/changes.js} +40 -74
  128. package/dist/stack/changes.js.map +1 -0
  129. package/dist/stack/client.d.ts +247 -0
  130. package/dist/stack/client.d.ts.map +1 -0
  131. package/dist/stack/client.js +9 -0
  132. package/dist/stack/client.js.map +1 -0
  133. package/dist/stack/identity-bindings.d.ts.map +1 -0
  134. package/dist/{identity-bindings.js → stack/identity-bindings.js} +5 -14
  135. package/dist/stack/identity-bindings.js.map +1 -0
  136. package/dist/stack/install-app.d.ts +22 -0
  137. package/dist/stack/install-app.d.ts.map +1 -0
  138. package/dist/stack/install-app.js +262 -0
  139. package/dist/stack/install-app.js.map +1 -0
  140. package/dist/stack/integrity.d.ts +94 -0
  141. package/dist/stack/integrity.d.ts.map +1 -0
  142. package/dist/stack/integrity.js +268 -0
  143. package/dist/stack/integrity.js.map +1 -0
  144. package/dist/{limits.d.ts → stack/limits.d.ts} +2 -5
  145. package/dist/stack/limits.d.ts.map +1 -0
  146. package/dist/{limits.js → stack/limits.js} +3 -6
  147. package/dist/stack/limits.js.map +1 -0
  148. package/dist/stack/migrations.d.ts +59 -0
  149. package/dist/stack/migrations.d.ts.map +1 -0
  150. package/dist/stack/migrations.js +141 -0
  151. package/dist/stack/migrations.js.map +1 -0
  152. package/dist/stack/reads.d.ts +69 -0
  153. package/dist/stack/reads.d.ts.map +1 -0
  154. package/dist/stack/reads.js +141 -0
  155. package/dist/stack/reads.js.map +1 -0
  156. package/dist/stack/record-id.d.ts +35 -0
  157. package/dist/stack/record-id.d.ts.map +1 -0
  158. package/dist/stack/record-id.js +82 -0
  159. package/dist/stack/record-id.js.map +1 -0
  160. package/dist/stack/stack.d.ts +444 -0
  161. package/dist/stack/stack.d.ts.map +1 -0
  162. package/dist/stack/stack.js +1339 -0
  163. package/dist/stack/stack.js.map +1 -0
  164. package/dist/stack/system-types.d.ts +16 -0
  165. package/dist/stack/system-types.d.ts.map +1 -0
  166. package/dist/stack/system-types.js +111 -0
  167. package/dist/stack/system-types.js.map +1 -0
  168. package/dist/stack/type-grants.d.ts +20 -0
  169. package/dist/stack/type-grants.d.ts.map +1 -0
  170. package/dist/stack/type-grants.js +69 -0
  171. package/dist/stack/type-grants.js.map +1 -0
  172. package/dist/stack/write-expectation.d.ts +79 -0
  173. package/dist/stack/write-expectation.d.ts.map +1 -0
  174. package/dist/stack/write-expectation.js +71 -0
  175. package/dist/stack/write-expectation.js.map +1 -0
  176. package/dist/stack/write-gate.d.ts +23 -0
  177. package/dist/stack/write-gate.d.ts.map +1 -0
  178. package/dist/stack/write-gate.js +17 -0
  179. package/dist/stack/write-gate.js.map +1 -0
  180. package/dist/testing.d.ts +44 -33
  181. package/dist/testing.d.ts.map +1 -1
  182. package/dist/testing.js +180 -176
  183. package/dist/testing.js.map +1 -1
  184. package/dist/type-handle.d.ts +67 -78
  185. package/dist/type-handle.d.ts.map +1 -1
  186. package/dist/type-handle.js +44 -111
  187. package/dist/type-handle.js.map +1 -1
  188. package/dist/types/adapter.d.ts +282 -0
  189. package/dist/types/adapter.d.ts.map +1 -0
  190. package/dist/types/adapter.js +5 -0
  191. package/dist/types/adapter.js.map +1 -0
  192. package/dist/types/associations.d.ts +140 -0
  193. package/dist/types/associations.d.ts.map +1 -0
  194. package/dist/types/associations.js +6 -0
  195. package/dist/types/associations.js.map +1 -0
  196. package/dist/types/capabilities.d.ts +89 -0
  197. package/dist/types/capabilities.d.ts.map +1 -0
  198. package/dist/types/capabilities.js +5 -0
  199. package/dist/types/capabilities.js.map +1 -0
  200. package/dist/types/events.d.ts +150 -0
  201. package/dist/types/events.d.ts.map +1 -0
  202. package/dist/types/events.js +5 -0
  203. package/dist/types/events.js.map +1 -0
  204. package/dist/types/ids.d.ts +43 -0
  205. package/dist/types/ids.d.ts.map +1 -0
  206. package/dist/types/ids.js +5 -0
  207. package/dist/types/ids.js.map +1 -0
  208. package/dist/types/index.d.ts +19 -0
  209. package/dist/types/index.d.ts.map +1 -0
  210. package/dist/types/index.js +19 -0
  211. package/dist/types/index.js.map +1 -0
  212. package/dist/types/journal.d.ts +47 -0
  213. package/dist/types/journal.d.ts.map +1 -0
  214. package/dist/types/journal.js +5 -0
  215. package/dist/types/journal.js.map +1 -0
  216. package/dist/types/query.d.ts +185 -0
  217. package/dist/types/query.d.ts.map +1 -0
  218. package/dist/types/query.js +10 -0
  219. package/dist/types/query.js.map +1 -0
  220. package/dist/types/records.d.ts +76 -0
  221. package/dist/types/records.d.ts.map +1 -0
  222. package/dist/types/records.js +5 -0
  223. package/dist/types/records.js.map +1 -0
  224. package/dist/types/schema.d.ts +74 -0
  225. package/dist/types/schema.d.ts.map +1 -0
  226. package/dist/types/schema.js +5 -0
  227. package/dist/types/schema.js.map +1 -0
  228. package/dist/types/system.d.ts +161 -0
  229. package/dist/types/system.d.ts.map +1 -0
  230. package/dist/types/system.js +32 -0
  231. package/dist/types/system.js.map +1 -0
  232. package/dist/types/tokens.d.ts +39 -0
  233. package/dist/types/tokens.d.ts.map +1 -0
  234. package/dist/types/tokens.js +5 -0
  235. package/dist/types/tokens.js.map +1 -0
  236. package/dist/validate.d.ts +31 -70
  237. package/dist/validate.d.ts.map +1 -1
  238. package/dist/validate.js +52 -92
  239. package/dist/validate.js.map +1 -1
  240. package/dist/{attachment-download.d.ts → wire/attachment-download.d.ts} +0 -57
  241. package/dist/wire/attachment-download.d.ts.map +1 -0
  242. package/dist/{attachment-download.js → wire/attachment-download.js} +0 -61
  243. package/dist/wire/attachment-download.js.map +1 -0
  244. package/dist/{auth.d.ts → wire/auth.d.ts} +5 -8
  245. package/dist/wire/auth.d.ts.map +1 -0
  246. package/dist/{auth.js → wire/auth.js} +5 -8
  247. package/dist/wire/auth.js.map +1 -0
  248. package/dist/{wire-body.d.ts → wire/body.d.ts} +35 -12
  249. package/dist/wire/body.d.ts.map +1 -0
  250. package/dist/{wire-body.js → wire/body.js} +74 -13
  251. package/dist/wire/body.js.map +1 -0
  252. package/dist/{wire-entry.d.ts → wire/index.d.ts} +12 -12
  253. package/dist/wire/index.d.ts.map +1 -0
  254. package/dist/{wire-entry.js → wire/index.js} +13 -17
  255. package/dist/wire/index.js.map +1 -0
  256. package/dist/wire/record.d.ts +31 -0
  257. package/dist/wire/record.d.ts.map +1 -0
  258. package/dist/{wire-record.js → wire/record.js} +7 -67
  259. package/dist/wire/record.js.map +1 -0
  260. package/dist/{wire-request.d.ts → wire/request.d.ts} +32 -49
  261. package/dist/wire/request.d.ts.map +1 -0
  262. package/dist/{wire-request.js → wire/request.js} +113 -83
  263. package/dist/wire/request.js.map +1 -0
  264. package/package.json +7 -7
  265. package/dist/adapter-entry.d.ts +0 -16
  266. package/dist/adapter-entry.d.ts.map +0 -1
  267. package/dist/adapter-entry.js +0 -14
  268. package/dist/adapter-entry.js.map +0 -1
  269. package/dist/attachment-download.d.ts.map +0 -1
  270. package/dist/attachment-download.js.map +0 -1
  271. package/dist/auth.d.ts.map +0 -1
  272. package/dist/auth.js.map +0 -1
  273. package/dist/changes.d.ts.map +0 -1
  274. package/dist/changes.js.map +0 -1
  275. package/dist/combine.d.ts.map +0 -1
  276. package/dist/combine.js.map +0 -1
  277. package/dist/did-entry.d.ts.map +0 -1
  278. package/dist/did-entry.js.map +0 -1
  279. package/dist/did.d.ts.map +0 -1
  280. package/dist/did.js.map +0 -1
  281. package/dist/identity-bindings.d.ts.map +0 -1
  282. package/dist/identity-bindings.js.map +0 -1
  283. package/dist/limits.d.ts.map +0 -1
  284. package/dist/limits.js.map +0 -1
  285. package/dist/record-id.d.ts +0 -70
  286. package/dist/record-id.d.ts.map +0 -1
  287. package/dist/record-id.js +0 -127
  288. package/dist/record-id.js.map +0 -1
  289. package/dist/scoped-stack.d.ts +0 -549
  290. package/dist/scoped-stack.d.ts.map +0 -1
  291. package/dist/scoped-stack.js +0 -1301
  292. package/dist/scoped-stack.js.map +0 -1
  293. package/dist/sort.d.ts.map +0 -1
  294. package/dist/sort.js.map +0 -1
  295. package/dist/stack-reads.d.ts +0 -38
  296. package/dist/stack-reads.d.ts.map +0 -1
  297. package/dist/stack-reads.js +0 -79
  298. package/dist/stack-reads.js.map +0 -1
  299. package/dist/stack.d.ts +0 -1032
  300. package/dist/stack.d.ts.map +0 -1
  301. package/dist/stack.js +0 -2337
  302. package/dist/stack.js.map +0 -1
  303. package/dist/types.d.ts +0 -1278
  304. package/dist/types.d.ts.map +0 -1
  305. package/dist/types.js +0 -51
  306. package/dist/types.js.map +0 -1
  307. package/dist/wire-body.d.ts.map +0 -1
  308. package/dist/wire-body.js.map +0 -1
  309. package/dist/wire-entry.d.ts.map +0 -1
  310. package/dist/wire-entry.js.map +0 -1
  311. package/dist/wire-record.d.ts +0 -50
  312. package/dist/wire-record.d.ts.map +0 -1
  313. package/dist/wire-record.js.map +0 -1
  314. package/dist/wire-request.d.ts.map +0 -1
  315. package/dist/wire-request.js.map +0 -1
  316. /package/dist/{did.d.ts → did/did.d.ts} +0 -0
  317. /package/dist/{identity-bindings.d.ts → stack/identity-bindings.d.ts} +0 -0
@@ -0,0 +1,282 @@
1
+ /**
2
+ * The storage adapter interfaces and the per-call options Stack hands them.
3
+ */
4
+ import type { Association, AssociationEdit, AuthorityAssociation, DataAssociation } from './associations.js';
5
+ import type { StackCapabilities } from './capabilities.js';
6
+ import type { RecordChange, Unsubscribe, SubscribeOptions } from './events.js';
7
+ import type { RecordId, TypeId, BaseId, FileId, AppId, EntityId, Actor } from './ids.js';
8
+ import type { JournalEntryInput, RecordJournalEntry, JournalQuery } from './journal.js';
9
+ import type { StackQuery, QuerySort, 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
+ * Who is performing a mutation, stamped onto the record in the same write.
32
+ * `ScopedStack` supplies it from the request's identities; a caller of
33
+ * plain `Stack` supplies it only when reconstructing an attributed write.
34
+ * See docs/spec/data-model.md § Authorship and attribution.
35
+ */
36
+ export type ActorOptions = {
37
+ actor?: Actor;
38
+ };
39
+ /**
40
+ * Accepted by every mutating StackRecordAdapter method. The adapter
41
+ * appends the entry, allocating its `seq`, inside the SAME write as the
42
+ * mutation, so a crash cannot leave a change unjournaled.
43
+ */
44
+ export type JournalOptions = {
45
+ journal?: JournalEntryInput;
46
+ };
47
+ /**
48
+ * What every mutating StackRecordAdapter method that bumps `version` takes.
49
+ * deleteRecord() adds `purge`.
50
+ */
51
+ export type MutateOptions = IfVersionOptions & SnapshotOptions & ActorOptions & JournalOptions;
52
+ /**
53
+ * What every write that never bumps `version` takes: the precondition,
54
+ * checked atomically as a bumping write checks it, and the journal entry.
55
+ * No actor: such a write stamps nothing on the record, so its requester
56
+ * travels in the entry. See docs/spec/versioning.md § Version history.
57
+ */
58
+ export type AspectWriteOptions = IfVersionOptions & JournalOptions;
59
+ /**
60
+ * What the four element-set writes take: `expectSet` is the set `Stack`
61
+ * read and checked its rules against. An adapter compares it with the
62
+ * stored set inside its write and throws ElementSetMovedError on a
63
+ * mismatch, changing nothing. Omitted, the write is unconditional.
64
+ * See docs/spec/adapters.md § Editing associations.
65
+ */
66
+ export type ElementWriteOptions<E extends Association> = AspectWriteOptions & {
67
+ expectSet?: readonly E[];
68
+ };
69
+ /** A named sort as an adapter receives it: `Stack` has resolved its `direction`. */
70
+ export type AdapterSort = QuerySort & {
71
+ direction: 'asc' | 'desc';
72
+ };
73
+ /**
74
+ * A query without `presentAt`, which applies migrations — app code no
75
+ * adapter or server holds — with its defaults still open: what travels
76
+ * on the wire, and what resolveQuery() takes.
77
+ */
78
+ export type PlainQuery = Omit<StackQuery, 'presentAt'>;
79
+ /**
80
+ * A query as an adapter receives it, from resolveQuery(): every default
81
+ * resolved, so no adapter carries one. See docs/spec/data-model.md
82
+ * § Sorting and pagination.
83
+ */
84
+ export type AdapterQuery = Omit<PlainQuery, 'sort' | 'limit'> & {
85
+ sort: AdapterSort;
86
+ limit: number;
87
+ };
88
+ /**
89
+ * The Records one scoped request may act on with one verb, as data matched
90
+ * rather than rules applied: inside `fence` and inside `within`, where an
91
+ * absent part constrains nothing. See docs/spec/access-control.md § Reach.
92
+ */
93
+ export type Reach = {
94
+ /** Only Records in these families are in reach. */
95
+ fence?: BaseId[];
96
+ /** Records meeting one of these are in reach. */
97
+ within?: {
98
+ /** Every Record in these families. */
99
+ baseIds: BaseId[];
100
+ /** Records this subject authored in these families. */
101
+ authored?: {
102
+ subjectId: EntityId;
103
+ baseIds: BaseId[];
104
+ };
105
+ /** Records carrying every element of one of these sets, by association identity. */
106
+ permissions: AuthorityAssociation[][];
107
+ };
108
+ };
109
+ /** The metadata an upload's `_attachment@1` record carries beside its bytes. */
110
+ export type PutAttachmentOptions = {
111
+ mimeType: string;
112
+ filename?: string;
113
+ /** Attribution for the metadata record, as create()'s `appId`. */
114
+ appId?: AppId;
115
+ };
116
+ /**
117
+ * The record-storage half of an adapter: structured data, queries,
118
+ * associations, versioning, type definitions, and stack identity.
119
+ */
120
+ export interface StackRecordAdapter {
121
+ readonly capabilities: StackCapabilities;
122
+ /** DID of the stack owner. Set during adapter initialization. */
123
+ readonly ownerEntityId: EntityId;
124
+ /**
125
+ * IANA timezone string for this stack, or undefined if never set.
126
+ * Passthrough app metadata with no default — see docs/spec.md § The
127
+ * `_config` record.
128
+ */
129
+ readonly timezone: string | undefined;
130
+ /**
131
+ * Throws StackConflictError if `record.id` already exists — never a
132
+ * silent overwrite. The check must be atomic with the write (a PK/unique
133
+ * constraint or equivalent); Stack itself doesn't pre-check, so a raw
134
+ * adapter that skips this enforces nothing.
135
+ */
136
+ createRecord(record: StackRecord, opts?: JournalOptions): Promise<StackRecord>;
137
+ getRecord(id: RecordId): Promise<StackRecord | null>;
138
+ /**
139
+ * Merge a content patch, one level deep, into the content as it stands
140
+ * when the write lands. Bumps `version` and snapshots. Never touches
141
+ * `typeId`; see commitMigration(). See docs/spec/data-model.md § Mutations.
142
+ */
143
+ patchContent(id: RecordId, patch: Record<string, unknown | null>, opts?: MutateOptions): Promise<StackRecord>;
144
+ /**
145
+ * Returns the record this call acted on: as it now stands after a soft
146
+ * delete, and as it stood immediately before destruction after a
147
+ * purge — captured inside the same write, so nothing can observe or alter
148
+ * it in between. Null when there was no record to delete, which is the
149
+ * only case that mutates nothing.
150
+ */
151
+ deleteRecord(id: RecordId, opts?: {
152
+ purge?: boolean;
153
+ } & MutateOptions): Promise<StackRecord | null>;
154
+ /** Reverse a soft delete. Returns the record as it now stands. */
155
+ undeleteRecord(id: RecordId, opts?: MutateOptions): Promise<StackRecord>;
156
+ queryRecords(query: AdapterQuery): Promise<QueryResult>;
157
+ /**
158
+ * queryRecords() over the Records in `reach` alone: the reach is one
159
+ * more condition of the query, so the page, its cursor and whether one
160
+ * comes back are decided among those Records only. Optional — a stack
161
+ * whose adapter lacks it cannot be scoped, as a server-backed one never
162
+ * needs to be. See docs/spec/adapters.md § Querying within a reach.
163
+ */
164
+ queryReadable?(query: AdapterQuery, reach: Reach): Promise<QueryResult>;
165
+ /** `null` moves the record to the root. */
166
+ setParent(id: RecordId, parentId: RecordId | null, opts?: AspectWriteOptions): Promise<StackRecord>;
167
+ /** Stamps `unlistedAt` fresh on `true`; clears it on `false`. */
168
+ setUnlisted(id: RecordId, unlisted: boolean, opts?: AspectWriteOptions): Promise<StackRecord>;
169
+ /**
170
+ * Apply adds and removes to the record's data associations as one write.
171
+ * See docs/spec/adapters.md § Editing associations.
172
+ */
173
+ editAssociations(id: RecordId, edits: AssociationEdit[], opts?: ElementWriteOptions<DataAssociation>): Promise<StackRecord>;
174
+ /** Replace the record's data associations with exactly `associations`. */
175
+ setAssociations(id: RecordId, associations: DataAssociation[], opts?: ElementWriteOptions<DataAssociation>): Promise<StackRecord>;
176
+ /** editAssociations() over the record's permissions. */
177
+ editAccess(id: RecordId, edits: AssociationEdit[], opts?: ElementWriteOptions<AuthorityAssociation>): Promise<StackRecord>;
178
+ /** Replace the record's permissions with exactly `permissions`; `[]` is private. */
179
+ setAccess(id: RecordId, permissions: AuthorityAssociation[], opts?: ElementWriteOptions<AuthorityAssociation>): Promise<StackRecord>;
180
+ /**
181
+ * Snapshots newest first; omitting `query` reads every version.
182
+ * See docs/spec/versioning.md § Version history.
183
+ */
184
+ getVersions(id: RecordId, query?: VersionsQuery): Promise<RecordVersion[]>;
185
+ getVersion(id: RecordId, version: number): Promise<RecordVersion | null>;
186
+ /**
187
+ * Standalone snapshot write, outside of a mutation's own atomic path.
188
+ * Mutating methods above take a `snapshot` option instead, so the
189
+ * snapshot and the mutation land in one write — see SnapshotOptions.
190
+ */
191
+ saveVersion(id: RecordId, version: RecordVersion): Promise<void>;
192
+ /**
193
+ * Read a record's change journal, oldest first — required, on the same
194
+ * footing as getVersions(). A recovery mechanism an app cannot rely on is
195
+ * most of the way to no mechanism at all, so an adapter with no journal
196
+ * refuses the call rather than declining to have the method.
197
+ * See docs/spec/journal.md § Reading it.
198
+ */
199
+ getJournal(id: RecordId, query?: JournalQuery): Promise<RecordJournalEntry[]>;
200
+ /**
201
+ * Restore a record to a previous version's `content` and `typeId` —
202
+ * everything a snapshot carries. Containment, listing and associations
203
+ * are left where they stand, there being nothing to restore them *from*.
204
+ * Bumps version internally; throws StackNotFoundError if the version
205
+ * doesn't exist.
206
+ */
207
+ restoreVersion(id: RecordId, version: number, opts?: MutateOptions): Promise<StackRecord>;
208
+ /**
209
+ * Commit a migration: write new content under a new typeId in one step.
210
+ * This is the only way a record's typeId changes after creation — used by
211
+ * Stack.commitMigration() and Stack.migrateAll(); patchContent() never
212
+ * changes typeId as a side effect. Bumps version internally.
213
+ */
214
+ commitMigration(id: RecordId, toTypeId: TypeId, content: Record<string, unknown>, opts?: MutateOptions): Promise<StackRecord>;
215
+ saveType(type: StackType): Promise<void>;
216
+ getType(id: TypeId): Promise<StackType | null>;
217
+ listTypes(): Promise<StackType[]>;
218
+ /**
219
+ * Atomically verify fileId is unreferenced and purge its metadata
220
+ * records, returning them; StackConflictError if still referenced.
221
+ * Optional — Stack.deleteAttachment() has a non-atomic fallback.
222
+ * The metadata records are those in the `metadataBaseId` family, matched
223
+ * as `filter.baseId` matches one. See docs/spec/attachments.md § Deleting
224
+ * attachments.
225
+ */
226
+ deleteUnreferencedAttachmentRecords?(fileId: FileId, metadataBaseId: BaseId): Promise<StackRecord[]>;
227
+ /**
228
+ * Relay changes that originated elsewhere — the inverse direction from
229
+ * `Stack`, which emits every change made through it. Optional, and
230
+ * absent on every local adapter: exactly one process owns a stack's
231
+ * storage, so locally there is no third party whose writes could have
232
+ * been missed. See docs/spec/events.md § Where events come from.
233
+ */
234
+ subscribeChanges?(opts: SubscribeOptions, handler: (change: RecordChange) => void): Promise<Unsubscribe>;
235
+ flush?(): Promise<void>;
236
+ close?(): Promise<void>;
237
+ }
238
+ /** One stored blob, as reported by StackBlobAdapter.listBlobs(). */
239
+ export type BlobInfo = {
240
+ fileId: FileId;
241
+ size: number;
242
+ /** When the blob was written. Used to apply a GC grace period to fresh, not-yet-associated uploads. */
243
+ modifiedAt: Date;
244
+ };
245
+ /**
246
+ * The blob-storage half of an adapter. Handles raw binary data only;
247
+ * attachment metadata lives on _attachment@1 records in the record adapter.
248
+ */
249
+ export interface StackBlobAdapter {
250
+ putBlob(data: Uint8Array): Promise<FileId>;
251
+ /**
252
+ * Returns a plain `Uint8Array` (never a subclass such as `Buffer`) that the
253
+ * caller owns: changing it never changes the stored bytes.
254
+ */
255
+ getBlob(fileId: FileId): Promise<Uint8Array>;
256
+ deleteBlob(fileId: FileId): Promise<void>;
257
+ /**
258
+ * Enumerate every blob currently in storage. Optional — without it,
259
+ * garbage collection can't find bare-bytes orphans (bytes with no
260
+ * metadata record at all). See docs/spec/attachments.md § Garbage
261
+ * collection.
262
+ */
263
+ listBlobs?(): Promise<BlobInfo[]>;
264
+ flush?(): Promise<void>;
265
+ close?(): Promise<void>;
266
+ }
267
+ /**
268
+ * A complete adapter: record storage and blob storage combined.
269
+ * Pass this to Stack.open(). Build one with combineAdapters() when you
270
+ * want different backends for records and blobs (e.g. SQLite + S3).
271
+ */
272
+ export type StackAdapter = StackRecordAdapter & StackBlobAdapter & {
273
+ /**
274
+ * Store bytes and create the accompanying _attachment@1 record as one
275
+ * atomic operation. Optional; implement only when bytes and records
276
+ * live behind a single boundary (today: APIAdapter alone), and never
277
+ * synthesized by combineAdapters(). A security boundary, not an
278
+ * efficiency shortcut — see docs/spec/adapters.md § Interface split.
279
+ */
280
+ putAttachmentWithMetadata?(data: Uint8Array, opts: PutAttachmentOptions): Promise<StackRecord>;
281
+ };
282
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/types/adapter.ts"],"names":[],"mappings":"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"}
@@ -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,140 @@
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 `editAssociations()`/`setAssociations()` 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
+ //# sourceMappingURL=associations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"associations.d.ts","sourceRoot":"","sources":["../../src/types/associations.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAE3D,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,QAAQ,CAAC;CAC/B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;CACpB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,iDAAiD;AACjD,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,YAAY,GAAG,cAAc,CAAC;AAE9E,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,kBAAkB,CAAC;CAC5B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,yGAAyG;AACzG,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GACf;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,qBAAqB,GAAG,iBAAiB,CAAC;AAE7E;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,qBAAqB,GAAG,uBAAuB,CAAC;AAE/F;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,oBAAoB,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,GACvC;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,WAAW,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAA;CAAE,GAClE;IAAE,EAAE,EAAE,QAAQ,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,CAAC;AAE/C;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,iBAAiB,EAAE;IAAE,EAAE,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Associations: the edges a Record carries, authority and data alike,
3
+ * and the change shapes that move them.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=associations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"associations.js","sourceRoot":"","sources":["../../src/types/associations.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * What a Stack and its adapter honor, and what a query can be refused for.
3
+ */
4
+ import type { NativeSortField } from './query.js';
5
+ /**
6
+ * How far into `content` a filter key may reach. The rungs nest, so they
7
+ * are one ordered value rather than booleans that can spell an impossible
8
+ * state. An unrecognized value reads as `'none'`: a refusal is recoverable,
9
+ * an unfiltered superset passed off as filtered is not.
10
+ * See docs/spec/adapters.md § Adapter capabilities.
11
+ */
12
+ export type ContentFilterReach =
13
+ /** No `filter.content` and no `filter.contentPresent` at all. */
14
+ 'none'
15
+ /** Single-segment field names only (`'did'`). */
16
+ | 'field'
17
+ /** Multi-segment paths too (`'emails.value'`). */
18
+ | 'path';
19
+ /**
20
+ * What a Stack — and the adapter under it — honors. Every `filter`/`sort`
21
+ * entry is named for the query key it gates, so the capability a query
22
+ * needs is derivable from the query. `limits` are numbers to pre-check
23
+ * against, not features. See docs/spec/adapters.md § Adapter capabilities.
24
+ */
25
+ export type StackCapabilities = {
26
+ filter: {
27
+ /**
28
+ * Required `'path'` for local/in-process adapters; a wire adapter may
29
+ * report a shallower rung, driven by the server's discovery response.
30
+ * Stack.query() throws StackBadRequestError rather than silently widening.
31
+ */
32
+ content: ContentFilterReach;
33
+ /**
34
+ * Whether `filter.contentPresent` is honored. Beside the reach ladder,
35
+ * not on it: matching a value promises nothing about answering whether
36
+ * one is there. Meaningful only where `content` is not `'none'`.
37
+ */
38
+ contentPresent: boolean;
39
+ /**
40
+ * Whether `filter.contentByType` is honored. Local adapters must; a
41
+ * collection facing `false` queries its handle's version alone rather
42
+ * than failing. Meaningful only where `content` is not `'none'`. See
43
+ * docs/spec/adapters.md § Adapter capabilities.
44
+ */
45
+ contentByType: boolean;
46
+ /**
47
+ * Whether `filter.search` is honored. Not a rung on the ladder: a
48
+ * full-text index is a different mechanism from field matching, and
49
+ * neither implies the other. Local adapters may decline it.
50
+ */
51
+ search: boolean;
52
+ };
53
+ sort: {
54
+ /** Which native columns this adapter can order by; see NativeSortField. */
55
+ fields: NativeSortField[];
56
+ /**
57
+ * Whether `sort.contentField` is honored. A boolean rather than names
58
+ * in `fields`: an adapter that sorts by content indexes every top-level
59
+ * scalar. Independent of `filter.content`.
60
+ */
61
+ contentField: boolean;
62
+ /** Whether `sort.contentFieldByType` is honored, as `filter.contentByType`. */
63
+ contentFieldByType: boolean;
64
+ };
65
+ /**
66
+ * Ceilings a client can check before spending a request; the server's
67
+ * own limit stays authoritative. `null` means this client cannot
68
+ * pre-check, not that nothing is enforced — local adapters declare it.
69
+ * See docs/spec/adapters.md § Adapter capabilities.
70
+ */
71
+ limits: {
72
+ /** Maximum attachment upload size in bytes. */
73
+ attachmentBytes: number | null;
74
+ /**
75
+ * Maximum serialized size in bytes of a Record's content — a create
76
+ * body or a merge patch. Stack.create()/Stack.patchContent() pre-check
77
+ * against it and throw StackPayloadTooLargeError before sending.
78
+ */
79
+ contentBytes: number | null;
80
+ };
81
+ };
82
+ /**
83
+ * A capability a query can be refused for, as its path into
84
+ * StackCapabilities — the same name the spec and a discovery response
85
+ * use, so an error says which key to look at. `limits` never appears: a
86
+ * ceiling is not something a query can lack.
87
+ */
88
+ export type MissingCapability = 'filter.content' | 'filter.contentPresent' | 'filter.contentByType' | 'filter.search' | 'sort.fields' | 'sort.contentField' | 'sort.contentFieldByType';
89
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/types/capabilities.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB;AAC5B,iEAAiE;AAC/D,MAAM;AACR,iDAAiD;GAC/C,OAAO;AACT,kDAAkD;GAChD,MAAM,CAAC;AAEX;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE;QACN;;;;WAIG;QACH,OAAO,EAAE,kBAAkB,CAAC;QAC5B;;;;WAIG;QACH,cAAc,EAAE,OAAO,CAAC;QACxB;;;;;WAKG;QACH,aAAa,EAAE,OAAO,CAAC;QACvB;;;;WAIG;QACH,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,IAAI,EAAE;QACJ,2EAA2E;QAC3E,MAAM,EAAE,eAAe,EAAE,CAAC;QAC1B;;;;WAIG;QACH,YAAY,EAAE,OAAO,CAAC;QACtB,+EAA+E;QAC/E,kBAAkB,EAAE,OAAO,CAAC;KAC7B,CAAC;IACF;;;;;OAKG;IACH,MAAM,EAAE;QACN,+CAA+C;QAC/C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B;;;;WAIG;QACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B,CAAC;CACH,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GACzB,gBAAgB,GAChB,uBAAuB,GACvB,sBAAsB,GACtB,eAAe,GACf,aAAa,GACb,mBAAmB,GACnB,yBAAyB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * What a Stack and its adapter honor, and what a query can be refused for.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/types/capabilities.ts"],"names":[],"mappings":"AAAA;;GAEG"}