apps 0.0.1-beta.8 → 0.0.1-beta.81

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 (180) hide show
  1. package/README.md +25 -22
  2. package/framework-reference.json +1 -1
  3. package/js/{chunk-72JNVHPK.js → chunk-4NFSABEA.js} +4 -3
  4. package/js/chunk-5FHWNLCI.js +88 -0
  5. package/js/chunk-5WGONRKQ.js +426 -0
  6. package/js/{chunk-M3B3DE4K.js → chunk-74YVXBKY.js} +463 -218
  7. package/js/chunk-CDXQDN7W.js +92 -0
  8. package/js/{chunk-UK573G7W.js → chunk-EOPQ727L.js} +87 -51
  9. package/js/{chunk-27F7W2LG.js → chunk-H2CJWXA3.js} +2 -2
  10. package/js/{chunk-JU7VHODU.js → chunk-H72MEDMN.js} +65 -10
  11. package/js/{chunk-FL2QR3XW.js → chunk-HJG4RBYM.js} +333 -69
  12. package/js/chunk-I6Q7ZPKJ.js +49 -0
  13. package/js/{chunk-CDL5PM2Q.js → chunk-IFJU5SYQ.js} +19082 -18402
  14. package/js/{chunk-VFZKSM3T.js → chunk-JPEUKEV4.js} +3 -3
  15. package/js/{chunk-5T57N25Q.js → chunk-KGCTYL2S.js} +511 -63
  16. package/js/{chunk-KUMBKVJD.js → chunk-KLYSEHUD.js} +2 -2
  17. package/js/{chunk-WLE7WX2U.js → chunk-NG56RPCA.js} +2348 -472
  18. package/js/chunk-OD3KFKZD.js +1617 -0
  19. package/js/{chunk-Z5M2LQOZ.js → chunk-OY47QPQY.js} +67 -55
  20. package/js/{chunk-57RKNWL2.js → chunk-PD6I2SDG.js} +4 -4
  21. package/js/chunk-PL5KOEZD.js +334 -0
  22. package/js/chunk-Q4IZAUIF.js +285 -0
  23. package/js/{chunk-RJDDBDSN.js → chunk-QWQM3CLH.js} +795 -177
  24. package/js/{chunk-RFVIONFX.js → chunk-TE25A7D6.js} +123 -44
  25. package/js/{chunk-IJX4CYZO.js → chunk-TUMGL2OC.js} +228 -264
  26. package/js/chunk-W6XCQAXP.js +171 -0
  27. package/js/chunk-WCGAO3X5.js +348 -0
  28. package/js/{chunk-IPI4MFSN.js → chunk-XBG7HHXC.js} +2 -2
  29. package/js/{chunk-CMYUWAX7.js → chunk-YQUG4CES.js} +126 -31
  30. package/js/{chunk-UESPOTUI.js → chunk-Z2SWTZCF.js} +861 -231
  31. package/js/client.js +142 -94
  32. package/js/contracts.js +127 -26
  33. package/js/effect.js +19 -19
  34. package/js/{es-APDZKREY.js → es-DIULA3ZF.js} +62 -1659
  35. package/js/graphql.js +50 -40
  36. package/js/host.js +83 -58
  37. package/js/index.js +131 -46
  38. package/js/mcp/effect.js +23 -21
  39. package/js/mcp/stdio.js +44 -34
  40. package/js/mcp.js +76 -53
  41. package/js/openapi.js +4071 -1357
  42. package/js/react.js +2 -3
  43. package/js/skills/effect.js +6 -3
  44. package/js/skills.js +208 -81
  45. package/js/storage/facet.js +1 -540
  46. package/js/ui/auth/contracts.js +2 -2
  47. package/js/ui/auth.js +5 -5
  48. package/js/ui/contracts.js +5 -4
  49. package/js/ui/serving.js +8604 -223
  50. package/package.json +3 -4
  51. package/runtime.json +1 -1
  52. package/types/app-cache/src/contracts/cache.d.ts +18 -0
  53. package/types/app-cache/src/index.d.ts +34 -2
  54. package/types/apps/src/contracts/api-response-error.d.ts +4 -0
  55. package/types/apps/src/contracts/app.d.ts +7 -3
  56. package/types/apps/src/contracts/cache.d.ts +20 -0
  57. package/types/apps/src/contracts/context.d.ts +19 -11
  58. package/types/apps/src/contracts/elicitation.d.ts +23 -7
  59. package/types/apps/src/contracts/events.d.ts +93 -0
  60. package/types/apps/src/contracts/failure.d.ts +30 -1
  61. package/types/apps/src/contracts/graphql.d.ts +2 -1
  62. package/types/apps/src/contracts/host.d.ts +649 -17
  63. package/types/apps/src/contracts/live.d.ts +2 -0
  64. package/types/apps/src/contracts/mcp.d.ts +80 -10
  65. package/types/apps/src/contracts/network.d.ts +120 -0
  66. package/types/apps/src/contracts/openapi-compile.d.ts +82 -3
  67. package/types/apps/src/contracts/openapi.d.ts +41 -9
  68. package/types/apps/src/contracts/operations.d.ts +8 -4
  69. package/types/apps/src/contracts/placement.d.ts +102 -0
  70. package/types/apps/src/contracts/protocol-version.d.ts +2 -2
  71. package/types/apps/src/contracts/protocols/1.d.ts +733 -81
  72. package/types/apps/src/contracts/protocols/10.d.ts +1450 -0
  73. package/types/apps/src/contracts/protocols/2.d.ts +69 -26
  74. package/types/apps/src/contracts/protocols/3.d.ts +133 -33
  75. package/types/apps/src/contracts/protocols/4.d.ts +122 -45
  76. package/types/apps/src/contracts/protocols/5.d.ts +157 -47
  77. package/types/apps/src/contracts/protocols/6.d.ts +1629 -0
  78. package/types/apps/src/contracts/protocols/7.d.ts +1785 -0
  79. package/types/apps/src/contracts/protocols/8.d.ts +1182 -0
  80. package/types/apps/src/contracts/protocols/9.d.ts +1104 -0
  81. package/types/apps/src/contracts/protocols/current.d.ts +3843 -0
  82. package/types/apps/src/contracts/protocols/oauth-6.d.ts +74 -0
  83. package/types/apps/src/contracts/protocols/oauth.d.ts +134 -0
  84. package/types/apps/src/contracts/provider-error.d.ts +9 -0
  85. package/types/apps/src/contracts/provider.d.ts +90 -6
  86. package/types/apps/src/contracts/skills.d.ts +50 -13
  87. package/types/apps/src/contracts/sql.d.ts +63 -0
  88. package/types/apps/src/contracts/ui.d.ts +37 -3
  89. package/types/apps/src/contracts/workflows.d.ts +6 -0
  90. package/types/apps/src/facet.d.ts +4 -5
  91. package/types/apps/src/host.d.ts +5 -0
  92. package/types/apps/src/implementation/account-router.d.ts +4 -3
  93. package/types/apps/src/implementation/authoring.d.ts +25 -5
  94. package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
  95. package/types/apps/src/implementation/cache.d.ts +28 -1
  96. package/types/apps/src/implementation/catalog-cache.d.ts +35 -4
  97. package/types/apps/src/implementation/elicitation.d.ts +18 -15
  98. package/types/apps/src/implementation/events.d.ts +59 -0
  99. package/types/apps/src/implementation/failure-detail.d.ts +25 -3
  100. package/types/apps/src/implementation/graphql-catalog.d.ts +3 -3
  101. package/types/apps/src/implementation/graphql.d.ts +4 -3
  102. package/types/apps/src/implementation/input-problems.d.ts +6 -2
  103. package/types/apps/src/implementation/invocation-timing.d.ts +18 -0
  104. package/types/apps/src/implementation/live.d.ts +2 -2
  105. package/types/apps/src/implementation/mcp-call.d.ts +6 -5
  106. package/types/apps/src/implementation/mcp-catalog.d.ts +6 -4
  107. package/types/apps/src/implementation/mcp-client.d.ts +17 -9
  108. package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
  109. package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
  110. package/types/apps/src/implementation/mcp.d.ts +20 -9
  111. package/types/apps/src/implementation/network.d.ts +16 -0
  112. package/types/apps/src/implementation/openapi-compile.d.ts +26 -6
  113. package/types/apps/src/implementation/openapi-document.d.ts +46 -19
  114. package/types/apps/src/implementation/openapi-names.d.ts +9 -4
  115. package/types/apps/src/implementation/openapi-request.d.ts +10 -2
  116. package/types/apps/src/implementation/openapi-source.d.ts +18 -0
  117. package/types/apps/src/implementation/openapi-upgrade.d.ts +4 -0
  118. package/types/apps/src/implementation/operations.d.ts +17 -2
  119. package/types/apps/src/implementation/optimistic.d.ts +1 -1
  120. package/types/apps/src/implementation/placement.d.ts +60 -0
  121. package/types/apps/src/implementation/protocol-operations.d.ts +3 -0
  122. package/types/apps/src/implementation/provider-error.d.ts +28 -1
  123. package/types/apps/src/implementation/provider.d.ts +18 -3
  124. package/types/apps/src/implementation/query-commit.d.ts +1 -1
  125. package/types/apps/src/implementation/router-catalog.d.ts +11 -13
  126. package/types/apps/src/implementation/router.d.ts +16 -5
  127. package/types/apps/src/implementation/runtime-yield.d.ts +7 -0
  128. package/types/apps/src/implementation/schema.d.ts +90 -10
  129. package/types/apps/src/implementation/skills.d.ts +18 -24
  130. package/types/apps/src/implementation/sql.d.ts +71 -0
  131. package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
  132. package/types/apps/src/implementation/ui-auth.d.ts +1 -1
  133. package/types/apps/src/implementation/ui-client.d.ts +2 -2
  134. package/types/apps/src/implementation/ui-document.d.ts +5 -0
  135. package/types/apps/src/implementation/ui-errors.d.ts +1 -1
  136. package/types/apps/src/implementation/ui-serving.d.ts +28 -9
  137. package/types/apps/src/implementation/ui-watch.d.ts +1 -1
  138. package/types/apps/src/implementation/upstream-error.d.ts +7 -0
  139. package/types/apps/src/implementation/webhooks.d.ts +1 -1
  140. package/types/apps/src/implementation/workflows.d.ts +1 -1
  141. package/types/apps/src/index.d.ts +55 -13
  142. package/types/apps/src/mcp.d.ts +20 -1
  143. package/types/apps/src/openapi.d.ts +1 -1
  144. package/types/apps/src/react.d.ts +1 -1
  145. package/types/apps/src/skills.d.ts +10 -8
  146. package/types/apps/src/ui-serving.d.ts +1 -1
  147. package/types/telemetry/src/app-records.d.ts +42 -0
  148. package/types/telemetry/src/browser-operations.d.ts +2 -2
  149. package/types/telemetry/src/browser.d.ts +8 -3
  150. package/types/telemetry/src/config.d.ts +2 -2
  151. package/types/telemetry/src/index.d.ts +2 -1
  152. package/types/telemetry/src/layer.d.ts +10 -4
  153. package/types/telemetry/src/measurements.d.ts +1 -1
  154. package/types/telemetry/src/ownership.d.ts +60 -0
  155. package/types/telemetry/src/recorded-failure.d.ts +29 -0
  156. package/types/telemetry/src/relay.d.ts +16 -6
  157. package/types/telemetry/src/span-attributes.d.ts +17 -1
  158. package/types/telemetry/src/transport.d.ts +8 -1
  159. package/types/utils/src/api-error.d.ts +55 -0
  160. package/types/utils/src/connection-failure.d.ts +33 -0
  161. package/types/utils/src/recorded-message.d.ts +18 -0
  162. package/types/utils/src/user-facing-error.d.ts +83 -0
  163. package/js/chunk-MKWZPDR6.js +0 -63
  164. package/js/chunk-N7YDVXYJ.js +0 -186
  165. package/js/chunk-NKLWZJLE.js +0 -172
  166. package/js/chunk-OCYUEU47.js +0 -224
  167. package/js/chunk-PJJ24GU7.js +0 -877
  168. package/js/chunk-PZB6T6KU.js +0 -19
  169. package/js/chunk-R3EV5FTO.js +0 -97
  170. package/js/chunk-YXQHV65J.js +0 -242
  171. package/js/chunk-ZQINWV4W.js +0 -630
  172. package/types/app-data/src/implementation/cursor.d.ts +0 -10
  173. package/types/app-data/src/implementation/index-key.d.ts +0 -7
  174. package/types/app-data/src/implementation/promise.d.ts +0 -68
  175. package/types/app-data/src/implementation/range.d.ts +0 -8
  176. package/types/app-data/src/implementation/schema.d.ts +0 -18
  177. package/types/app-data/src/implementation/sqlite.d.ts +0 -11
  178. package/types/app-data/src/index.d.ts +0 -4
  179. package/types/apps/src/contracts/storage.d.ts +0 -68
  180. package/types/apps/src/implementation/storage.d.ts +0 -15
@@ -1,630 +0,0 @@
1
- import {
2
- AppDatabaseError,
3
- DatabaseFieldReserved,
4
- DatabaseLimitExceeded,
5
- DatabaseLimits,
6
- DatabaseOperation,
7
- DatabaseSchema,
8
- PaginationResult,
9
- RangeClause,
10
- Row,
11
- RowMetadata,
12
- defaultDatabaseLimits,
13
- defaultDatabaseRuntimeLimits,
14
- reservedFieldNames
15
- } from "./chunk-N7YDVXYJ.js";
16
- import {
17
- Cause_exports,
18
- Clock_exports,
19
- Effect_exports,
20
- Encoding_exports,
21
- Schema_exports,
22
- Semaphore_exports
23
- } from "./chunk-CDL5PM2Q.js";
24
-
25
- // ../app-data/src/implementation/schema.ts
26
- var metadata = new Set(reservedFieldNames);
27
- var reserved = (name) => metadata.has(name);
28
- var indexesFor = (table) => [{ name: "by_creation", fields: [] }, ...table.indexes].map((index) => ({
29
- name: index.name,
30
- fields: [
31
- ...index.fields,
32
- ...["createdAt", "id"].filter((field) => !index.fields.includes(field))
33
- ]
34
- }));
35
- var fieldFor = (table, name) => metadata.has(name) ? { kind: "string" } : Object.hasOwn(table.fields, name) ? table.fields[name] : void 0;
36
- var validScalar = (field, value) => field.kind === "number" ? typeof value === "number" && Number.isFinite(value) : field.kind === "boolean" ? typeof value === "boolean" : typeof value === "string" && ![...value].some((character) => {
37
- const point = character.codePointAt(0);
38
- return point !== void 0 && point >= 55296 && point <= 57343;
39
- });
40
- var parseDatabaseSchema = (input) => Schema_exports.decodeUnknownEffect(DatabaseSchema)(input).pipe(
41
- Effect_exports.mapError(() => new AppDatabaseError({ reason: "schema" })),
42
- Effect_exports.flatMap(
43
- (schema) => Effect_exports.gen(function* () {
44
- for (const [name, table] of Object.entries(schema)) {
45
- const field = Object.keys(table.fields).find(reserved);
46
- if (field !== void 0) return yield* new DatabaseFieldReserved({ table: name, field });
47
- if (new Set(table.indexes.map((index) => index.name)).size !== table.indexes.length)
48
- return yield* new AppDatabaseError({ reason: "schema" });
49
- for (const field2 of Object.values(table.fields)) {
50
- if ((field2.kind === "id" ? field2.references === void 0 : field2.references !== void 0) || field2.default !== void 0 && !validScalar(field2, field2.default) || field2.references !== void 0 && !Object.hasOwn(schema, field2.references))
51
- return yield* new AppDatabaseError({ reason: "schema" });
52
- }
53
- for (const index of table.indexes)
54
- if (index.name === "by_creation" || new Set(index.fields).size !== index.fields.length || index.fields.some((name2) => fieldFor(table, name2) === void 0))
55
- return yield* new AppDatabaseError({ reason: "schema" });
56
- }
57
- return schema;
58
- })
59
- )
60
- );
61
- var canonicalSchema = (schema) => JSON.stringify(
62
- Object.fromEntries(
63
- Object.entries(schema).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([name, table]) => [
64
- name,
65
- {
66
- fields: Object.fromEntries(
67
- Object.entries(table.fields).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([field, definition]) => [
68
- field,
69
- {
70
- kind: definition.kind,
71
- optional: definition.optional === true,
72
- ...definition.default === void 0 ? {} : { default: definition.default },
73
- ...definition.references === void 0 ? {} : { references: definition.references }
74
- }
75
- ])
76
- ),
77
- indexes: [...table.indexes].sort(
78
- (a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0
79
- )
80
- }
81
- ])
82
- )
83
- );
84
- var writeValue = (table, values, previous, meta) => Effect_exports.gen(function* () {
85
- if (Object.keys(values).some((name) => metadata.has(name) || !Object.hasOwn(table.fields, name)))
86
- return yield* new AppDatabaseError({ reason: "value" });
87
- const row = { ...meta };
88
- for (const [name, field] of Object.entries(table.fields)) {
89
- const supplied = Object.hasOwn(values, name) ? values[name] : previous?.[name];
90
- if (supplied === null && !field.optional)
91
- return yield* new AppDatabaseError({ reason: "value" });
92
- const value = supplied === null || supplied === void 0 ? field.default : supplied;
93
- if (value === void 0) {
94
- if (!field.optional) return yield* new AppDatabaseError({ reason: "value" });
95
- } else {
96
- if (!validScalar(field, value)) return yield* new AppDatabaseError({ reason: "value" });
97
- row[name] = value;
98
- }
99
- }
100
- return row;
101
- });
102
-
103
- // ../app-data/src/implementation/cursor.ts
104
- var Payload = Schema_exports.Struct({
105
- version: Schema_exports.Literal(1),
106
- query: Schema_exports.String,
107
- key: Schema_exports.String
108
- });
109
- var fingerprint = (crypto, value) => Effect_exports.tryPromise({
110
- try: async () => Encoding_exports.encodeBase64Url(
111
- new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value)))
112
- ),
113
- catch: () => new AppDatabaseError({ reason: "storage" })
114
- });
115
- var cursorCodec = (crypto, bytes) => Effect_exports.gen(function* () {
116
- const key = yield* Effect_exports.tryPromise({
117
- try: () => crypto.subtle.importKey("raw", new Uint8Array(bytes), "AES-GCM", false, [
118
- "encrypt",
119
- "decrypt"
120
- ]),
121
- catch: () => new AppDatabaseError({ reason: "storage" })
122
- });
123
- return {
124
- encode: (query, position) => Effect_exports.tryPromise({
125
- try: async () => {
126
- const nonce = crypto.getRandomValues(new Uint8Array(12));
127
- const plaintext = new TextEncoder().encode(
128
- JSON.stringify({ version: 1, query, key: Encoding_exports.encodeBase64Url(position) })
129
- );
130
- const ciphertext = new Uint8Array(
131
- await crypto.subtle.encrypt({ name: "AES-GCM", iv: nonce }, key, plaintext)
132
- );
133
- const token = new Uint8Array(nonce.length + ciphertext.length);
134
- token.set(nonce);
135
- token.set(ciphertext, nonce.length);
136
- return Encoding_exports.encodeBase64Url(token);
137
- },
138
- catch: () => new AppDatabaseError({ reason: "cursor" })
139
- }),
140
- decode: (query, token) => Effect_exports.gen(function* () {
141
- if (token.length > defaultDatabaseRuntimeLimits.maxCursorChars)
142
- return yield* new AppDatabaseError({ reason: "cursor" });
143
- const encoded = yield* Effect_exports.fromResult(Encoding_exports.decodeBase64Url(token));
144
- if (encoded.length < 28) return yield* new AppDatabaseError({ reason: "cursor" });
145
- const plain = yield* Effect_exports.tryPromise(
146
- () => crypto.subtle.decrypt(
147
- { name: "AES-GCM", iv: new Uint8Array(encoded.slice(0, 12)) },
148
- key,
149
- new Uint8Array(encoded.slice(12))
150
- )
151
- );
152
- const payload = yield* Schema_exports.decodeUnknownEffect(Schema_exports.fromJsonString(Payload))(
153
- new TextDecoder().decode(plain)
154
- );
155
- if (payload.query !== query) return yield* new AppDatabaseError({ reason: "cursor" });
156
- return yield* Effect_exports.fromResult(Encoding_exports.decodeBase64Url(payload.key));
157
- }).pipe(Effect_exports.mapError(() => new AppDatabaseError({ reason: "cursor" })))
158
- };
159
- });
160
-
161
- // ../app-data/src/implementation/index-key.ts
162
- var encodeIndexKey = (values, maximum = defaultDatabaseLimits.indexBytes) => Effect_exports.try({
163
- try: () => {
164
- const bytes = [1];
165
- for (const value of values) {
166
- if (value === null) bytes.push(1);
167
- else if (typeof value === "boolean") bytes.push(value ? 17 : 16);
168
- else if (typeof value === "string") {
169
- if ([...value].some((character) => {
170
- const code = character.codePointAt(0);
171
- return code !== void 0 && code >= 55296 && code <= 57343;
172
- }))
173
- throw new Error("Invalid string");
174
- bytes.push(32);
175
- for (const byte of new TextEncoder().encode(value)) {
176
- bytes.push(byte);
177
- if (byte === 0) bytes.push(255);
178
- }
179
- bytes.push(0, 0);
180
- } else {
181
- if (!Number.isFinite(value)) throw new Error("Invalid number");
182
- const view = new DataView(new ArrayBuffer(8));
183
- view.setFloat64(0, value === 0 ? 0 : value, false);
184
- const encoded = new Uint8Array(view.buffer);
185
- if (value < 0) for (const [i, byte] of encoded.entries()) encoded[i] = 255 ^ byte;
186
- else view.setUint8(0, view.getUint8(0) ^ 128);
187
- bytes.push(48, ...encoded);
188
- }
189
- if (bytes.length > maximum) throw new Error("Index key too long");
190
- }
191
- return Uint8Array.from(bytes);
192
- },
193
- catch: () => new AppDatabaseError({ reason: "value" })
194
- });
195
- var prefixEnd = (prefix) => {
196
- const result = prefix.slice();
197
- for (let i = result.length - 1; i >= 0; i--) {
198
- const byte = result[i];
199
- if (byte !== void 0 && byte < 255) {
200
- result[i] = byte + 1;
201
- return result.slice(0, i + 1);
202
- }
203
- }
204
- return void 0;
205
- };
206
-
207
- // ../app-data/src/implementation/range.ts
208
- var queryBounds = (table, plan, maximum) => Effect_exports.gen(function* () {
209
- const index = indexesFor(table).find((index2) => index2.name === plan.index);
210
- if (index === void 0) return yield* new AppDatabaseError({ reason: "index" });
211
- const equal = [];
212
- let rangeField;
213
- let lower;
214
- let upper;
215
- let lowerSet = false;
216
- let upperSet = false;
217
- for (const clause of plan.clauses) {
218
- const expected = rangeField === void 0 ? index.fields[equal.length] : rangeField;
219
- const field = fieldFor(table, clause.field);
220
- if (expected !== clause.field || field === void 0)
221
- return yield* new AppDatabaseError({ reason: "range" });
222
- if (clause.op === "eq") {
223
- if (rangeField !== void 0 || (clause.value === null ? !field.optional : !validScalar(field, clause.value)))
224
- return yield* new AppDatabaseError({ reason: "range" });
225
- equal.push(clause.value);
226
- } else {
227
- if (!validScalar(field, clause.value))
228
- return yield* new AppDatabaseError({ reason: "range" });
229
- rangeField = clause.field;
230
- const encoded = yield* encodeIndexKey([...equal, clause.value], maximum);
231
- if (clause.op === "gt" || clause.op === "gte") {
232
- if (lowerSet) return yield* new AppDatabaseError({ reason: "range" });
233
- lowerSet = true;
234
- lower = clause.op === "gt" ? prefixEnd(encoded) : encoded;
235
- } else {
236
- if (upperSet) return yield* new AppDatabaseError({ reason: "range" });
237
- upperSet = true;
238
- upper = clause.op === "lte" ? prefixEnd(encoded) : encoded;
239
- }
240
- }
241
- }
242
- const prefix = yield* encodeIndexKey(equal, maximum);
243
- if (rangeField !== void 0 && !lowerSet)
244
- lower = prefixEnd(yield* encodeIndexKey([...equal, null], maximum));
245
- return { lower: lower ?? prefix, upper: upper ?? prefixEnd(prefix) };
246
- });
247
-
248
- // ../app-data/src/implementation/sqlite.ts
249
- var Saved = Schema_exports.Struct({ schema_hash: Schema_exports.String, cursor_key: Schema_exports.String });
250
- var StoredRow = Schema_exports.Struct({ body: Schema_exports.String });
251
- var ScanRow = Schema_exports.Struct({ sort_key: Schema_exports.Uint8Array, body: Schema_exports.String });
252
- var CountRow = Schema_exports.Struct({ sort_key: Schema_exports.Uint8Array });
253
- var decodeRows = Schema_exports.decodeUnknownEffect(Schema_exports.Array(StoredRow));
254
- var decodeBody = Schema_exports.decodeUnknownEffect(Schema_exports.fromJsonString(Row));
255
- var storageError = () => new AppDatabaseError({ reason: "storage" });
256
- var makeSqliteDatabase = (options) => Effect_exports.gen(function* () {
257
- const { sql, crypto } = options;
258
- const schema = yield* parseDatabaseSchema(options.schema).pipe(
259
- Effect_exports.catchTag(
260
- "DatabaseFieldReserved",
261
- () => Effect_exports.fail(new AppDatabaseError({ reason: "schema" }))
262
- )
263
- );
264
- const limits = yield* Schema_exports.decodeUnknownEffect(DatabaseLimits)(
265
- options.limits ?? defaultDatabaseLimits
266
- ).pipe(Effect_exports.mapError(() => new AppDatabaseError({ reason: "limit" })));
267
- const schemaHash = yield* fingerprint(crypto, canonicalSchema(schema));
268
- const key = yield* sql.withTransaction(
269
- Effect_exports.gen(function* () {
270
- yield* sql`CREATE TABLE IF NOT EXISTS app_database (singleton INTEGER PRIMARY KEY CHECK (singleton = 1), schema_hash TEXT NOT NULL, cursor_key TEXT NOT NULL)`;
271
- yield* sql`CREATE TABLE IF NOT EXISTS app_rows (table_name TEXT NOT NULL, id TEXT NOT NULL, body TEXT NOT NULL, PRIMARY KEY (table_name, id)) WITHOUT ROWID`;
272
- yield* sql`CREATE TABLE IF NOT EXISTS app_indexes (table_name TEXT NOT NULL, index_name TEXT NOT NULL, sort_key BLOB NOT NULL, row_id TEXT NOT NULL, PRIMARY KEY (table_name, index_name, sort_key)) WITHOUT ROWID`;
273
- yield* sql`CREATE TABLE IF NOT EXISTS app_mutation_receipts (id TEXT PRIMARY KEY, fingerprint TEXT NOT NULL, result TEXT NOT NULL) WITHOUT ROWID`;
274
- yield* sql`CREATE INDEX IF NOT EXISTS app_indexes_by_row ON app_indexes (table_name, row_id)`;
275
- const generated = Encoding_exports.encodeBase64Url(crypto.getRandomValues(new Uint8Array(32)));
276
- yield* sql`INSERT OR IGNORE INTO app_database (singleton, schema_hash, cursor_key) VALUES (1, ${schemaHash}, ${generated})`;
277
- const saved = yield* sql`SELECT schema_hash, cursor_key FROM app_database WHERE singleton = 1`.pipe(
278
- Effect_exports.flatMap((rows) => Schema_exports.decodeUnknownEffect(Saved)(rows[0]))
279
- );
280
- if (saved.schema_hash !== schemaHash)
281
- return yield* new AppDatabaseError({ reason: "schema_changed" });
282
- return yield* Effect_exports.fromResult(Encoding_exports.decodeBase64Url(saved.cursor_key));
283
- })
284
- ).pipe(
285
- Effect_exports.catchTags({
286
- SqlError: () => Effect_exports.fail(storageError()),
287
- SchemaError: () => Effect_exports.fail(storageError()),
288
- EncodingError: () => Effect_exports.fail(storageError())
289
- })
290
- );
291
- const cursors = yield* cursorCodec(crypto, key);
292
- const run = (writable, work) => sql.withTransaction(
293
- Effect_exports.gen(function* () {
294
- const context = yield* Effect_exports.context();
295
- const gate = yield* Semaphore_exports.make(1);
296
- const reads = /* @__PURE__ */ new Set();
297
- const changes = /* @__PURE__ */ new Set();
298
- let active = true;
299
- let failed;
300
- const used = {
301
- rowsRead: 0,
302
- rowsReturned: 0,
303
- bytesRead: 0,
304
- writes: 0,
305
- scanCalls: 0,
306
- directGets: 0
307
- };
308
- const charge = (name, amount) => Effect_exports.suspend(() => {
309
- used[name] += amount;
310
- return used[name] > limits[name] ? Effect_exports.fail(
311
- new DatabaseLimitExceeded({
312
- limit: name,
313
- maximum: limits[name],
314
- requested: used[name]
315
- })
316
- ) : Effect_exports.void;
317
- });
318
- const get = (table, id) => Effect_exports.gen(function* () {
319
- yield* charge("directGets", 1);
320
- reads.add(table);
321
- const records = yield* sql`SELECT body FROM app_rows WHERE table_name = ${table} AND id = ${id}`.pipe(
322
- Effect_exports.flatMap(decodeRows)
323
- );
324
- const record = records[0];
325
- if (record === void 0) return null;
326
- yield* charge("rowsRead", 1);
327
- yield* charge("bytesRead", new TextEncoder().encode(record.body).length);
328
- return yield* decodeBody(record.body);
329
- });
330
- const store = (tableName, table, row) => Effect_exports.gen(function* () {
331
- const meta = yield* Schema_exports.decodeUnknownEffect(RowMetadata)(row);
332
- const body = JSON.stringify(row);
333
- const bytes = new TextEncoder().encode(body).length;
334
- if (bytes > limits.valueBytes)
335
- return yield* new DatabaseLimitExceeded({
336
- limit: "valueBytes",
337
- maximum: limits.valueBytes,
338
- requested: bytes
339
- });
340
- const keys = yield* Effect_exports.forEach(
341
- indexesFor(table),
342
- (index) => encodeIndexKey(
343
- index.fields.map(
344
- (field) => Object.hasOwn(row, field) ? row[field] ?? null : null
345
- ),
346
- limits.indexBytes
347
- ).pipe(Effect_exports.map((key2) => ({ name: index.name, key: key2 })))
348
- );
349
- yield* sql`INSERT INTO app_rows (table_name, id, body) VALUES (${tableName}, ${meta.id}, ${body}) ON CONFLICT(table_name, id) DO UPDATE SET body = excluded.body`;
350
- yield* sql`DELETE FROM app_indexes WHERE table_name = ${tableName} AND row_id = ${meta.id}`;
351
- for (const index of keys)
352
- yield* sql`INSERT INTO app_indexes (table_name, index_name, sort_key, row_id) VALUES (${tableName}, ${index.name}, ${index.key}, ${meta.id})`;
353
- changes.add(tableName);
354
- return row;
355
- });
356
- const execute = (input) => gate.withPermits(1)(
357
- Effect_exports.gen(function* () {
358
- if (!active) return yield* new AppDatabaseError({ reason: "closed" });
359
- if (failed !== void 0) return yield* failed;
360
- const operation = yield* Schema_exports.decodeUnknownEffect(DatabaseOperation)(
361
- input
362
- ).pipe(Effect_exports.mapError(() => new AppDatabaseError({ reason: "value" })));
363
- const tableName = operation.kind === "query" ? operation.plan.table : operation.table;
364
- const table = Object.hasOwn(schema, tableName) ? schema[tableName] : void 0;
365
- if (table === void 0) return yield* new AppDatabaseError({ reason: "table" });
366
- switch (operation.kind) {
367
- case "get": {
368
- const row = yield* get(tableName, operation.id);
369
- if (row !== null) yield* charge("rowsReturned", 1);
370
- return row;
371
- }
372
- case "insert": {
373
- if (!writable) return yield* new AppDatabaseError({ reason: "readonly" });
374
- yield* charge("writes", 1);
375
- const timestamp = new Date(yield* Clock_exports.currentTimeMillis).toISOString();
376
- const row = yield* writeValue(table, operation.value, void 0, {
377
- id: crypto.randomUUID(),
378
- createdAt: timestamp,
379
- updatedAt: timestamp
380
- });
381
- return yield* store(tableName, table, row);
382
- }
383
- case "update": {
384
- if (!writable) return yield* new AppDatabaseError({ reason: "readonly" });
385
- yield* charge("writes", 1);
386
- const before = yield* get(tableName, operation.id);
387
- if (before === null) return null;
388
- const meta = yield* Schema_exports.decodeUnknownEffect(RowMetadata)(before);
389
- const row = yield* writeValue(table, operation.patch, before, {
390
- ...meta,
391
- updatedAt: new Date(yield* Clock_exports.currentTimeMillis).toISOString()
392
- });
393
- return yield* store(tableName, table, row);
394
- }
395
- case "delete": {
396
- if (!writable) return yield* new AppDatabaseError({ reason: "readonly" });
397
- yield* charge("writes", 1);
398
- const before = yield* get(tableName, operation.id);
399
- if (before === null) return false;
400
- yield* sql`DELETE FROM app_rows WHERE table_name = ${tableName} AND id = ${operation.id}`;
401
- yield* sql`DELETE FROM app_indexes WHERE table_name = ${tableName} AND row_id = ${operation.id}`;
402
- changes.add(tableName);
403
- return true;
404
- }
405
- case "query": {
406
- const { plan, terminal } = operation;
407
- const bounds = yield* queryBounds(table, plan, limits.indexBytes);
408
- reads.add(tableName);
409
- yield* charge("scanCalls", 1);
410
- const remaining = terminal.kind === "count" ? limits.rowsRead - used.rowsRead : limits.rowsReturned - used.rowsReturned;
411
- const count = terminal.kind === "first" ? 1 : terminal.kind === "take" ? terminal.count : terminal.kind === "paginate" ? terminal.numItems : remaining;
412
- if ((terminal.kind === "take" || terminal.kind === "paginate") && count > limits.rowsReturned)
413
- return yield* new DatabaseLimitExceeded({
414
- limit: "pageSize",
415
- maximum: limits.rowsReturned,
416
- requested: count
417
- });
418
- if (count === 0 && terminal.kind === "take") return [];
419
- const query = yield* fingerprint(
420
- crypto,
421
- JSON.stringify({
422
- schemaHash,
423
- table: tableName,
424
- index: plan.index,
425
- order: plan.order,
426
- lower: Encoding_exports.encodeBase64Url(bounds.lower),
427
- upper: bounds.upper === void 0 ? null : Encoding_exports.encodeBase64Url(bounds.upper)
428
- })
429
- );
430
- const position = terminal.kind === "paginate" && terminal.cursor !== null ? yield* cursors.decode(query, terminal.cursor) : void 0;
431
- const predicates = [
432
- sql`i.table_name = ${tableName}`,
433
- sql`i.index_name = ${plan.index}`,
434
- sql`i.sort_key >= ${bounds.lower}`
435
- ];
436
- if (bounds.upper !== void 0)
437
- predicates.push(sql`i.sort_key < ${bounds.upper}`);
438
- if (position !== void 0)
439
- predicates.push(
440
- plan.order === "asc" ? sql`i.sort_key > ${position}` : sql`i.sort_key < ${position}`
441
- );
442
- const direction = plan.order === "asc" ? sql.literal("ASC") : sql.literal("DESC");
443
- const limit = Math.min(
444
- terminal.kind === "first" || terminal.kind === "take" ? count : count + 1,
445
- remaining + 1
446
- );
447
- if (terminal.kind === "count") {
448
- const rows2 = yield* sql`SELECT i.sort_key FROM app_indexes i WHERE ${sql.and(predicates)} ORDER BY i.sort_key ${direction} LIMIT ${limit}`.pipe(
449
- Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(Schema_exports.Array(CountRow)))
450
- );
451
- yield* charge("rowsRead", rows2.length);
452
- yield* charge(
453
- "bytesRead",
454
- rows2.reduce((sum, row) => sum + row.sort_key.byteLength, 0)
455
- );
456
- return rows2.length;
457
- }
458
- const rows = yield* sql`SELECT i.sort_key, r.body FROM app_indexes i JOIN app_rows r ON r.table_name = i.table_name AND r.id = i.row_id WHERE ${sql.and(predicates)} ORDER BY i.sort_key ${direction} LIMIT ${limit}`.pipe(
459
- Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(Schema_exports.Array(ScanRow)))
460
- );
461
- yield* charge("rowsRead", rows.length);
462
- yield* charge(
463
- "bytesRead",
464
- rows.reduce(
465
- (sum, row) => sum + new TextEncoder().encode(row.body).length + row.sort_key.byteLength,
466
- 0
467
- )
468
- );
469
- if (terminal.kind === "collect" && rows.length > count)
470
- return yield* new DatabaseLimitExceeded({
471
- limit: "rowsReturned",
472
- maximum: limits.rowsReturned,
473
- requested: used.rowsReturned + rows.length
474
- });
475
- const page = rows.slice(0, count);
476
- yield* charge("rowsReturned", page.length);
477
- const values = yield* Effect_exports.forEach(page, (row) => decodeBody(row.body));
478
- if (terminal.kind === "first") return values[0] ?? null;
479
- if (terminal.kind !== "paginate") return values;
480
- const last = page.at(-1);
481
- const isDone = rows.length <= count;
482
- return {
483
- page: values,
484
- isDone,
485
- continueCursor: isDone || last === void 0 ? null : yield* cursors.encode(query, last.sort_key)
486
- };
487
- }
488
- }
489
- }).pipe(
490
- Effect_exports.catchTags({
491
- SqlError: () => Effect_exports.fail(storageError()),
492
- SchemaError: () => Effect_exports.fail(storageError())
493
- }),
494
- Effect_exports.tapError(
495
- (error) => Effect_exports.sync(() => {
496
- failed = error;
497
- })
498
- ),
499
- Effect_exports.provideContext(context)
500
- )
501
- );
502
- const session = {
503
- readTables: reads,
504
- changedTables: changes,
505
- execute,
506
- once: (key2, expected, work2) => Effect_exports.gen(function* () {
507
- if (!active) return yield* new AppDatabaseError({ reason: "closed" });
508
- if (!writable) return yield* new AppDatabaseError({ reason: "readonly" });
509
- const rows = yield* sql`SELECT fingerprint, result FROM app_mutation_receipts WHERE id = ${key2}`.pipe(
510
- Effect_exports.flatMap(
511
- Schema_exports.decodeUnknownEffect(
512
- Schema_exports.Array(
513
- Schema_exports.Struct({ fingerprint: Schema_exports.String, result: Schema_exports.String })
514
- )
515
- )
516
- ),
517
- Effect_exports.mapError(storageError)
518
- );
519
- const saved = rows[0];
520
- if (saved !== void 0) {
521
- if (saved.fingerprint !== expected)
522
- return yield* new AppDatabaseError({ reason: "replay" });
523
- return yield* Schema_exports.decodeUnknownEffect(Schema_exports.fromJsonString(Schema_exports.Json))(
524
- saved.result
525
- ).pipe(Effect_exports.mapError(storageError));
526
- }
527
- const result = yield* work2();
528
- const encoded = yield* Schema_exports.encodeEffect(Schema_exports.fromJsonString(Schema_exports.Json))(
529
- result
530
- ).pipe(Effect_exports.mapError(storageError));
531
- if (new TextEncoder().encode(encoded).byteLength > 1024 * 1024)
532
- return yield* new AppDatabaseError({ reason: "limit" });
533
- yield* sql`INSERT INTO app_mutation_receipts (id, fingerprint, result) VALUES (${key2}, ${expected}, ${encoded})`.pipe(
534
- Effect_exports.mapError(storageError)
535
- );
536
- return result;
537
- })
538
- };
539
- return yield* Effect_exports.suspend(() => work(session)).pipe(
540
- // A failed database call poisons the session. Report that failure even when
541
- // authored code caught it or threw something else in its place.
542
- Effect_exports.catchCause(
543
- (cause) => failed === void 0 || Cause_exports.hasInterrupts(cause) ? Effect_exports.failCause(cause) : Effect_exports.fail(failed)
544
- ),
545
- Effect_exports.tap(
546
- () => gate.withPermits(1)(
547
- Effect_exports.suspend(() => failed === void 0 ? Effect_exports.void : Effect_exports.fail(failed))
548
- )
549
- ),
550
- Effect_exports.ensuring(
551
- Effect_exports.sync(() => {
552
- active = false;
553
- })
554
- )
555
- );
556
- })
557
- ).pipe(Effect_exports.catchTag("SqlError", () => Effect_exports.fail(storageError())));
558
- return {
559
- schema,
560
- schemaHash,
561
- read: (work) => run(false, work),
562
- mutate: (work) => run(true, work)
563
- };
564
- });
565
-
566
- // ../app-data/src/implementation/promise.ts
567
- var promiseTable = (session, table, signal) => {
568
- const execute = (input) => Effect_exports.runPromise(
569
- Schema_exports.decodeUnknownEffect(DatabaseOperation)(input).pipe(Effect_exports.flatMap(session.execute)),
570
- { signal }
571
- );
572
- const query = (plan) => ({
573
- order: (direction) => query({ ...plan, order: direction }),
574
- collect: async () => Schema_exports.decodeUnknownSync(Schema_exports.Array(Row))(
575
- await execute({ kind: "query", plan, terminal: { kind: "collect" } })
576
- ),
577
- count: async () => Schema_exports.decodeUnknownSync(Schema_exports.Int)(
578
- await execute({ kind: "query", plan, terminal: { kind: "count" } })
579
- ),
580
- first: async () => Schema_exports.decodeUnknownSync(Schema_exports.NullOr(Row))(
581
- await execute({ kind: "query", plan, terminal: { kind: "first" } })
582
- ),
583
- take: async (count) => Schema_exports.decodeUnknownSync(Schema_exports.Array(Row))(
584
- await execute({ kind: "query", plan, terminal: { kind: "take", count } })
585
- ),
586
- paginate: async (options) => Schema_exports.decodeUnknownSync(PaginationResult)(
587
- await execute({ kind: "query", plan, terminal: { kind: "paginate", ...options } })
588
- )
589
- });
590
- return {
591
- get: async (id) => Schema_exports.decodeUnknownSync(Schema_exports.NullOr(Row))(await execute({ kind: "get", table, id })),
592
- insert: async (value) => Schema_exports.decodeUnknownSync(Row)(await execute({ kind: "insert", table, value })),
593
- update: async (id, patch) => Schema_exports.decodeUnknownSync(Schema_exports.NullOr(Row))(
594
- await execute({ kind: "update", table, id, patch })
595
- ),
596
- delete: async (id) => Schema_exports.decodeUnknownSync(Schema_exports.Boolean)(await execute({ kind: "delete", table, id })),
597
- withIndex: (index, range) => {
598
- const ranges = /* @__PURE__ */ new WeakMap();
599
- const makeRange = (clauses2) => {
600
- const predicate = (op) => (field, value) => makeRange([
601
- ...clauses2,
602
- Schema_exports.decodeUnknownSync(RangeClause)({
603
- field,
604
- op,
605
- value: op === "eq" && value === void 0 ? null : value
606
- })
607
- ]);
608
- const result = {
609
- eq: predicate("eq"),
610
- gt: predicate("gt"),
611
- gte: predicate("gte"),
612
- lt: predicate("lt"),
613
- lte: predicate("lte")
614
- };
615
- ranges.set(result, clauses2);
616
- return result;
617
- };
618
- const selected = range === void 0 ? makeRange([]) : range(makeRange([]));
619
- const clauses = ranges.get(selected);
620
- if (clauses === void 0) throw new Error("Return the supplied index range");
621
- return query({ table, index, order: "asc", clauses });
622
- }
623
- };
624
- };
625
-
626
- export {
627
- parseDatabaseSchema,
628
- makeSqliteDatabase,
629
- promiseTable
630
- };
@@ -1,10 +0,0 @@
1
- /** Authenticated, opaque continuation tokens tied to one installation, schema and query plan. */
2
- import { Effect } from "effect";
3
- import { AppDatabaseError } from "../contracts/database.js";
4
- /** Stable SHA-256 fingerprints contain no raw query arguments in logs or metadata keys. */
5
- export declare const fingerprint: (crypto: Crypto, value: string) => Effect.Effect<string, AppDatabaseError, never>;
6
- /** Capture a per-database key. Nonces are fresh, and malformed/tampered/cross-query cursors fail closed. */
7
- export declare const cursorCodec: (crypto: Crypto, bytes: Uint8Array) => Effect.Effect<{
8
- encode: (query: string, position: Uint8Array) => Effect.Effect<string, AppDatabaseError, never>;
9
- decode: (query: string, token: string) => Effect.Effect<Uint8Array<ArrayBufferLike>, AppDatabaseError, never>;
10
- }, AppDatabaseError, never>;
@@ -1,7 +0,0 @@
1
- /** Order-preserving scalar tuples. SQLite BLOB ordering supplies bounded prefix/range scans. */
2
- import { Effect } from "effect";
3
- import { AppDatabaseError, type Scalar } from "../contracts/database.js";
4
- /** Compare UTF-8 strings, booleans and finite doubles consistently, with absence before present values. */
5
- export declare const encodeIndexKey: (values: readonly (Scalar | null)[], maximum?: number) => Effect.Effect<Uint8Array<ArrayBuffer>, AppDatabaseError, never>;
6
- /** Exclusive upper bound for all tuples beginning with this prefix. */
7
- export declare const prefixEnd: (prefix: Uint8Array) => Uint8Array | undefined;