apps 0.0.1-beta.0 → 0.0.1-beta.10

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 (141) hide show
  1. package/README.md +145 -30
  2. package/framework-reference.json +1 -1
  3. package/js/browser-XIPJGLH2.js +65 -0
  4. package/js/{chunk-36DNRFZQ.js → chunk-27F7W2LG.js} +1 -1
  5. package/js/{chunk-VFUZI3NY.js → chunk-57RKNWL2.js} +4 -4
  6. package/js/{chunk-BPEFS4YF.js → chunk-5T57N25Q.js} +122 -18
  7. package/js/chunk-72JNVHPK.js +41 -0
  8. package/js/{chunk-2OTCEKL2.js → chunk-CDL5PM2Q.js} +2643 -1646
  9. package/js/{chunk-KWTCHVLT.js → chunk-CRDWFA74.js} +69 -54
  10. package/js/chunk-CZ7CSFO4.js +39 -0
  11. package/js/{chunk-WIDTG42X.js → chunk-EPT3ZP52.js} +79 -26
  12. package/js/chunk-FL2QR3XW.js +507 -0
  13. package/js/{chunk-3ANFZFCV.js → chunk-IJX4CYZO.js} +15 -18
  14. package/js/chunk-IPI4MFSN.js +78 -0
  15. package/js/chunk-JU7VHODU.js +104 -0
  16. package/js/chunk-KUMBKVJD.js +39 -0
  17. package/js/{chunk-YDR4CPJA.js → chunk-M3B3DE4K.js} +8 -8
  18. package/js/chunk-MKWZPDR6.js +63 -0
  19. package/js/{chunk-7JXHF5IF.js → chunk-N7YDVXYJ.js} +49 -1
  20. package/js/chunk-NKLWZJLE.js +172 -0
  21. package/js/{chunk-OWD2YICM.js → chunk-ODEIDRGW.js} +116 -88
  22. package/js/{chunk-D6BKYP2L.js → chunk-PJJ24GU7.js} +4 -4
  23. package/js/{chunk-EP6AEUZO.js → chunk-PZB6T6KU.js} +1 -1
  24. package/js/chunk-R3EV5FTO.js +97 -0
  25. package/js/chunk-RFVIONFX.js +189 -0
  26. package/js/{chunk-W7Q5EOTS.js → chunk-UK573G7W.js} +32 -32
  27. package/js/chunk-UVL56Z6E.js +6641 -0
  28. package/js/{chunk-Q2FD5IBM.js → chunk-V5KNQVCT.js} +505 -124
  29. package/js/{chunk-SBKHUC5L.js → chunk-VFZKSM3T.js} +5 -25
  30. package/js/{chunk-HP7E42X6.js → chunk-WLE7WX2U.js} +1158 -232
  31. package/js/{chunk-X3YBZCJW.js → chunk-YXQHV65J.js} +58 -62
  32. package/js/chunk-Z5M2LQOZ.js +209 -0
  33. package/js/{chunk-R6JMJSVT.js → chunk-ZQINWV4W.js} +60 -20
  34. package/js/client.js +11 -27
  35. package/js/contracts.js +138 -27
  36. package/js/effect.js +20 -15
  37. package/js/es-APDZKREY.js +40968 -0
  38. package/js/graphql.js +220 -123
  39. package/js/host.js +75 -19
  40. package/js/index.js +261 -117
  41. package/js/mcp/effect.js +24 -17
  42. package/js/mcp/stdio.js +26 -21
  43. package/js/mcp.js +127 -26
  44. package/js/openapi.js +3048 -150
  45. package/js/operations/approval.js +1 -1
  46. package/js/react.js +4 -4
  47. package/js/skills/effect.js +11 -0
  48. package/js/skills.js +893 -0
  49. package/js/storage/facet.js +7 -7
  50. package/js/ui/auth/contracts.js +9 -10
  51. package/js/ui/auth.js +17 -15
  52. package/js/ui/contracts.js +5 -5
  53. package/js/ui/serving.js +14 -13
  54. package/package.json +9 -1
  55. package/runtime.json +1 -1
  56. package/types/app-cache/src/contracts/cache.d.ts +119 -0
  57. package/types/app-cache/src/index.d.ts +93 -0
  58. package/types/app-data/src/contracts/database.d.ts +33 -6
  59. package/types/app-data/src/implementation/schema.d.ts +2 -17
  60. package/types/apps/src/contracts/api-response-error.d.ts +43 -0
  61. package/types/apps/src/contracts/app.d.ts +16 -4
  62. package/types/apps/src/contracts/cache.d.ts +44 -0
  63. package/types/apps/src/contracts/dynamic-skills.d.ts +10 -0
  64. package/types/apps/src/contracts/failure.d.ts +25 -0
  65. package/types/apps/src/contracts/graphql.d.ts +18 -1
  66. package/types/apps/src/contracts/host.d.ts +76 -528
  67. package/types/apps/src/contracts/mcp.d.ts +19 -1
  68. package/types/apps/src/contracts/openapi-compile.d.ts +11 -0
  69. package/types/apps/src/contracts/openapi-document.d.ts +53 -0
  70. package/types/apps/src/contracts/openapi.d.ts +160 -30
  71. package/types/apps/src/contracts/operations.d.ts +0 -5
  72. package/types/apps/src/contracts/protocol-version.d.ts +6 -0
  73. package/types/apps/src/contracts/protocols/1.d.ts +1589 -0
  74. package/types/apps/src/contracts/protocols/2.d.ts +668 -0
  75. package/types/apps/src/contracts/protocols/3.d.ts +676 -0
  76. package/types/apps/src/contracts/protocols/4.d.ts +1229 -0
  77. package/types/apps/src/contracts/protocols/5.d.ts +1090 -0
  78. package/types/apps/src/contracts/provider-error.d.ts +15 -0
  79. package/types/apps/src/contracts/provider.d.ts +69 -6
  80. package/types/apps/src/contracts/router.d.ts +59 -0
  81. package/types/apps/src/contracts/skills.d.ts +122 -0
  82. package/types/apps/src/contracts/storage.d.ts +3 -3
  83. package/types/apps/src/contracts/swagger-client.d.ts +29 -0
  84. package/types/apps/src/contracts/ui-auth.d.ts +6 -14
  85. package/types/apps/src/contracts/workflows.d.ts +34 -3
  86. package/types/apps/src/graphql.d.ts +5 -7
  87. package/types/apps/src/host.d.ts +1 -0
  88. package/types/apps/src/implementation/account-router.d.ts +12 -0
  89. package/types/apps/src/implementation/app.d.ts +5 -4
  90. package/types/apps/src/implementation/cache-session.d.ts +7 -0
  91. package/types/apps/src/implementation/cache.d.ts +8 -0
  92. package/types/apps/src/implementation/catalog-cache.d.ts +36 -0
  93. package/types/apps/src/implementation/dynamic-skills.d.ts +7 -0
  94. package/types/apps/src/implementation/elicitation.d.ts +13 -13
  95. package/types/apps/src/implementation/failure-detail.d.ts +25 -0
  96. package/types/apps/src/implementation/git.d.ts +25 -0
  97. package/types/apps/src/implementation/graphql-catalog.d.ts +7 -0
  98. package/types/apps/src/implementation/graphql.d.ts +81 -3
  99. package/types/apps/src/implementation/inflate.d.ts +16 -0
  100. package/types/apps/src/implementation/input-problems.d.ts +3 -0
  101. package/types/apps/src/implementation/mcp-call.d.ts +3 -2
  102. package/types/apps/src/implementation/mcp-catalog.d.ts +9 -0
  103. package/types/apps/src/implementation/mcp-client.d.ts +39 -22
  104. package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
  105. package/types/apps/src/implementation/mcp-tools.d.ts +6 -3
  106. package/types/apps/src/implementation/mcp.d.ts +55 -2
  107. package/types/apps/src/implementation/openapi-compile.d.ts +120 -0
  108. package/types/apps/src/implementation/openapi-document.d.ts +51 -0
  109. package/types/apps/src/implementation/openapi-names.d.ts +18 -0
  110. package/types/apps/src/implementation/openapi-request.d.ts +10 -4
  111. package/types/apps/src/implementation/openapi-source.d.ts +36 -0
  112. package/types/apps/src/implementation/openapi.d.ts +39 -3
  113. package/types/apps/src/implementation/operations.d.ts +26 -3
  114. package/types/apps/src/implementation/protocol-operations.d.ts +3 -4
  115. package/types/apps/src/implementation/provider-error.d.ts +10 -0
  116. package/types/apps/src/implementation/provider.d.ts +9 -4
  117. package/types/apps/src/implementation/router-catalog.d.ts +225 -0
  118. package/types/apps/src/implementation/router.d.ts +59 -0
  119. package/types/apps/src/implementation/schema.d.ts +11 -6
  120. package/types/apps/src/implementation/skill-files.d.ts +10 -0
  121. package/types/apps/src/implementation/skills.d.ts +43 -0
  122. package/types/apps/src/implementation/storage.d.ts +5 -3
  123. package/types/apps/src/implementation/swagger-client.d.ts +28 -0
  124. package/types/apps/src/implementation/ui-auth.d.ts +11 -5
  125. package/types/apps/src/implementation/ui-serving.d.ts +4 -2
  126. package/types/apps/src/implementation/webhooks.d.ts +1 -1
  127. package/types/apps/src/implementation/workflow-context.d.ts +11 -3
  128. package/types/apps/src/index.d.ts +11 -3
  129. package/types/apps/src/mcp-stdio.d.ts +2 -5
  130. package/types/apps/src/mcp.d.ts +8 -7
  131. package/types/apps/src/openapi.d.ts +8 -6
  132. package/types/apps/src/skills.d.ts +75 -0
  133. package/types/apps/src/ui-auth.d.ts +2 -2
  134. package/types/telemetry/src/browser-operations.d.ts +5 -2
  135. package/types/telemetry/src/config.d.ts +2 -0
  136. package/js/chunk-22WRQZT7.js +0 -389
  137. package/js/chunk-BKVL7XAJ.js +0 -47
  138. package/js/chunk-C24KEZXR.js +0 -59
  139. package/js/chunk-LOKGDT6B.js +0 -28
  140. package/js/chunk-MLKGABMK.js +0 -9
  141. package/types/apps/src/implementation/account-operations.d.ts +0 -32
@@ -1,59 +1,50 @@
1
1
  import {
2
- parseDatabaseSchema,
3
2
  promiseTable
4
- } from "./chunk-R6JMJSVT.js";
3
+ } from "./chunk-ZQINWV4W.js";
5
4
  import {
6
- nativeOperation
7
- } from "./chunk-C24KEZXR.js";
5
+ declaredOperations,
6
+ fromPromise,
7
+ nativeOperation,
8
+ nativeRouter
9
+ } from "./chunk-Z5M2LQOZ.js";
8
10
  import {
9
11
  ScheduleTiming
10
- } from "./chunk-HP7E42X6.js";
12
+ } from "./chunk-WLE7WX2U.js";
13
+ import {
14
+ DatabaseSchema
15
+ } from "./chunk-N7YDVXYJ.js";
11
16
  import {
12
17
  decoderOf,
13
18
  isSchema,
14
19
  storageFieldOf
15
- } from "./chunk-BPEFS4YF.js";
20
+ } from "./chunk-5T57N25Q.js";
16
21
  import {
17
22
  AppStorageUnavailable
18
- } from "./chunk-EP6AEUZO.js";
23
+ } from "./chunk-PZB6T6KU.js";
19
24
  import {
20
25
  JsonValue
21
- } from "./chunk-36DNRFZQ.js";
26
+ } from "./chunk-27F7W2LG.js";
22
27
  import {
23
28
  Effect_exports,
24
29
  Schema_exports
25
- } from "./chunk-2OTCEKL2.js";
30
+ } from "./chunk-CDL5PM2Q.js";
26
31
 
27
- // src/implementation/authoring.ts
28
- var NativeCallback = /* @__PURE__ */ Symbol("apps.NativeCallback");
29
- var fromPromise = (callback) => (...args) => {
30
- if (NativeCallback in callback) {
31
- const native = callback[NativeCallback];
32
- return native(...args);
32
+ // src/contracts/http.ts
33
+ var ResponseStatusError = class extends Schema_exports.TaggedError()(
34
+ "ResponseStatusError",
35
+ { status: Schema_exports.Number }
36
+ ) {
37
+ get message() {
38
+ return `Request failed with status ${this.status}`;
33
39
  }
34
- return Effect_exports.tryPromise({ try: () => callback(...args), catch: (error) => error });
35
40
  };
36
- var toPromise = (operation, signal) => {
37
- const native = (...args) => Effect_exports.suspend(() => {
38
- if (signal === void 0) return operation(...args);
39
- if (signal.aborted) return Effect_exports.interrupt;
40
- const cancelled = Effect_exports.callback((resume) => {
41
- if (signal.aborted) {
42
- resume(Effect_exports.interrupt);
43
- return;
44
- }
45
- const abort = () => resume(Effect_exports.interrupt);
46
- signal.addEventListener("abort", abort, { once: true });
47
- return Effect_exports.sync(() => signal.removeEventListener("abort", abort));
48
- });
49
- return Effect_exports.raceFirst(
50
- cancelled,
51
- Effect_exports.suspend(() => operation(...args))
52
- );
53
- });
54
- return Object.assign((...args) => Effect_exports.runPromise(native(...args)), {
55
- [NativeCallback]: native
56
- });
41
+ var ResponseDecodeError = class extends Schema_exports.TaggedError()(
42
+ "ResponseDecodeError",
43
+ {}
44
+ ) {
45
+ get message() {
46
+ return "Response body did not match the expected schema";
47
+ }
57
48
  };
58
49
 
59
50
  // src/implementation/workflows.ts
@@ -79,8 +70,12 @@ var nativeWorkflow = (value) => {
79
70
  var InternalApp = /* @__PURE__ */ Symbol("apps.App");
80
71
  var isApp = (value) => typeof value === "object" && value !== null && InternalApp in value;
81
72
  var toEffectApp = (app) => app[InternalApp];
73
+ function rejectCatalogs(definition) {
74
+ if ("queries" in definition || "mutations" in definition)
75
+ throw new Error("Put queries and mutations in a router under tools");
76
+ }
82
77
  function adaptDefinition(definition) {
83
- if ("tools" in definition) throw new Error("Use queries and mutations instead of tools");
78
+ rejectCatalogs(definition);
84
79
  const webhooks = definition.webhooks === void 0 ? {} : {
85
80
  webhooks: Object.fromEntries(
86
81
  Object.entries(definition.webhooks).map(([name, webhook]) => [
@@ -96,42 +91,42 @@ function adaptDefinition(definition) {
96
91
  ])
97
92
  )
98
93
  };
99
- const operations = (kind, catalog) => Object.fromEntries(
100
- Object.entries(catalog).map(([name, value]) => {
101
- const operation = nativeOperation(value);
102
- if (operation === void 0 || operation.kind !== kind)
103
- throw new Error("Invalid app data operation");
104
- return [name, operation];
105
- })
106
- );
107
94
  const workflows = definition.workflows === void 0 ? {} : {
108
95
  workflows: Object.fromEntries(
109
96
  Object.entries(definition.workflows).map(([name, value]) => {
110
- const declared = nativeWorkflow(value);
111
- if (declared === void 0) throw new Error("Invalid workflow declaration");
112
- return [name, declared];
97
+ const declared2 = nativeWorkflow(value);
98
+ if (declared2 === void 0) throw new Error("Invalid workflow declaration");
99
+ return [name, declared2];
113
100
  })
114
101
  )
115
102
  };
116
- const data = {
117
- ...definition.queries === void 0 ? {} : { queries: operations("query", definition.queries) },
118
- ...definition.mutations === void 0 ? {} : { mutations: operations("mutation", definition.mutations) }
119
- };
103
+ const root = definition.tools === void 0 ? void 0 : nativeRouter(definition.tools);
104
+ if (definition.tools !== void 0 && root === void 0)
105
+ throw new Error("tools must be a router");
106
+ const data = root === void 0 ? {} : { tools: root };
107
+ const declared = root?.kind === "router" ? declaredOperations(root) : [];
108
+ const mutations = /* @__PURE__ */ new Set();
109
+ for (const { operation } of declared) {
110
+ if (operation.kind !== "mutation") continue;
111
+ if (mutations.has(operation))
112
+ throw new Error("A mutation can be mounted at only one path in tools");
113
+ mutations.add(operation);
114
+ }
120
115
  const schedules = definition.schedules === void 0 ? {} : {
121
116
  schedules: Object.fromEntries(
122
117
  Object.entries(definition.schedules).map(([name, schedule]) => {
123
- const matches = Object.entries(definition.mutations ?? {}).filter(
124
- ([, operation]) => operation === schedule.operation
118
+ const target = nativeOperation(schedule.operation);
119
+ const match = declared.find(
120
+ ({ operation }) => operation === target && operation.kind === "mutation"
125
121
  );
126
- const match = matches[0];
127
- if (match === void 0 || matches.length !== 1)
128
- throw new Error("A schedule must reference exactly one named mutation in this app");
122
+ if (match === void 0)
123
+ throw new Error("A schedule must reference a mutation in this app's tools");
129
124
  return [
130
125
  name,
131
126
  {
132
127
  timing: Schema_exports.decodeUnknownSync(ScheduleTiming)(schedule.timing),
133
128
  input: Schema_exports.decodeUnknownSync(JsonValue)(schedule.input),
134
- tool: `mutations.${match[0]}`
129
+ tool: match.name
135
130
  }
136
131
  ];
137
132
  })
@@ -146,6 +141,7 @@ function adaptDefinition(definition) {
146
141
  };
147
142
  }
148
143
  var defineApp = (requirements, definition) => {
144
+ if (typeof definition !== "function") rejectCatalogs(definition);
149
145
  const evaluate = typeof definition === "function" ? definition : async () => definition;
150
146
  const factory = fromPromise(evaluate);
151
147
  const native = {
@@ -183,7 +179,7 @@ var serialize = (tables) => {
183
179
  }
184
180
  ])
185
181
  );
186
- return Effect_exports.runSync(parseDatabaseSchema(definitions));
182
+ return Schema_exports.decodeUnknownSync(DatabaseSchema)(definitions);
187
183
  };
188
184
  var authorDatabase = (tables, session, signal, writable) => {
189
185
  return Object.fromEntries(
@@ -233,8 +229,8 @@ var unavailableStorage = {
233
229
  };
234
230
 
235
231
  export {
236
- fromPromise,
237
- toPromise,
232
+ ResponseStatusError,
233
+ ResponseDecodeError,
238
234
  workflow,
239
235
  isApp,
240
236
  toEffectApp,
@@ -0,0 +1,209 @@
1
+ import {
2
+ HostedTool,
3
+ RouterKey,
4
+ RouterMeta,
5
+ reservedRouterKeys
6
+ } from "./chunk-WLE7WX2U.js";
7
+ import {
8
+ decoderOf
9
+ } from "./chunk-5T57N25Q.js";
10
+ import {
11
+ Effect_exports,
12
+ Schema_exports
13
+ } from "./chunk-CDL5PM2Q.js";
14
+
15
+ // src/implementation/authoring.ts
16
+ var NativeCallback = /* @__PURE__ */ Symbol("apps.NativeCallback");
17
+ var fromPromise = (callback) => (...args) => {
18
+ if (NativeCallback in callback) {
19
+ const native = callback[NativeCallback];
20
+ return native(...args);
21
+ }
22
+ return Effect_exports.tryPromise({ try: () => callback(...args), catch: (error) => error });
23
+ };
24
+ var toPromise = (operation, signal) => {
25
+ const native = (...args) => Effect_exports.suspend(() => {
26
+ if (signal === void 0) return operation(...args);
27
+ if (signal.aborted) return Effect_exports.interrupt;
28
+ const cancelled = Effect_exports.callback((resume) => {
29
+ if (signal.aborted) {
30
+ resume(Effect_exports.interrupt);
31
+ return;
32
+ }
33
+ const abort = () => resume(Effect_exports.interrupt);
34
+ signal.addEventListener("abort", abort, { once: true });
35
+ return Effect_exports.sync(() => signal.removeEventListener("abort", abort));
36
+ });
37
+ return Effect_exports.raceFirst(
38
+ cancelled,
39
+ Effect_exports.suspend(() => operation(...args))
40
+ );
41
+ });
42
+ return Object.assign((...args) => Effect_exports.runPromise(native(...args)), {
43
+ [NativeCallback]: native
44
+ });
45
+ };
46
+
47
+ // src/implementation/operations.ts
48
+ var NativeOperation = /* @__PURE__ */ Symbol("apps.Operation");
49
+ var NativeRouterKey = /* @__PURE__ */ Symbol("apps.Router");
50
+ var operationDeclaration = (operation) => ({
51
+ kind: operation.kind,
52
+ [NativeOperation]: operation
53
+ });
54
+ var nativeOperation = (value) => {
55
+ if (typeof value !== "object" || value === null || !(NativeOperation in value)) return void 0;
56
+ return value[NativeOperation];
57
+ };
58
+ var operationOptions = (options) => {
59
+ const approval = options.approval;
60
+ return {
61
+ ...options.description === void 0 ? {} : { description: options.description },
62
+ ...options.title === void 0 ? {} : { title: options.title },
63
+ ...options.annotations === void 0 ? {} : { annotations: options.annotations },
64
+ ...options._meta === void 0 ? {} : { _meta: options._meta },
65
+ input: decoderOf(options.input),
66
+ ...approval === void 0 ? {} : {
67
+ approval: (context) => Effect_exports.tryPromise({ try: async () => approval(context), catch: (error) => error })
68
+ }
69
+ };
70
+ };
71
+ var withApproval = (operation, approval) => ({
72
+ ...operation,
73
+ [NativeOperation]: {
74
+ ...operation[NativeOperation],
75
+ approval: (context) => Effect_exports.tryPromise({ try: async () => approval(context), catch: (error) => error })
76
+ }
77
+ });
78
+ var make = (kind, options, run) => operationDeclaration({
79
+ ...operationOptions(options),
80
+ kind,
81
+ // The host always validates JSON serialization, even without a stronger output declaration.
82
+ ...options.output === void 0 ? {} : { output: decoderOf(options.output) },
83
+ run: (context, input) => Effect_exports.tryPromise({
84
+ // SAFETY: defineApp checks the handler context against its requirements.
85
+ // The host validates account bindings and creates the matching storage facade.
86
+ try: () => run(context, input),
87
+ catch: (error) => error
88
+ })
89
+ });
90
+ var query = (options, run) => make("query", options, run);
91
+ var mutation = (options, run) => make("mutation", options, run);
92
+
93
+ // src/implementation/router.ts
94
+ var routerDeclaration = (node) => ({
95
+ [NativeRouterKey]: node
96
+ });
97
+ var nativeRouter = (value) => {
98
+ if (typeof value !== "object" || value === null || !(NativeRouterKey in value)) return void 0;
99
+ return value[NativeRouterKey];
100
+ };
101
+ var nativeNode = (value) => nativeOperation(value) ?? nativeRouter(value);
102
+ var metaOf = (options) => {
103
+ if (options === void 0) return void 0;
104
+ const defined = Object.fromEntries(
105
+ Object.entries(options).filter(([, value]) => value !== void 0)
106
+ );
107
+ return Object.keys(defined).length === 0 ? void 0 : Schema_exports.decodeUnknownSync(RouterMeta)(defined);
108
+ };
109
+ var mergeMeta = (base, override) => base === void 0 ? override : override === void 0 ? base : { ...base, ...override };
110
+ function router(children, options) {
111
+ const meta = metaOf(options);
112
+ const existing = nativeRouter(children);
113
+ if (existing !== void 0)
114
+ return routerDeclaration(
115
+ existing.kind === "router" ? { ...existing, ...withMeta(mergeMeta(existing.meta, meta)) } : { ...existing, ...withOverrides(mergeMeta(existing.overrides, meta)) }
116
+ );
117
+ const nodes = {};
118
+ for (const [key, value] of Object.entries(children)) {
119
+ if (reservedRouterKeys.has(key)) throw new Error(`Router key "${key}" is reserved`);
120
+ if (!Schema_exports.is(RouterKey)(key))
121
+ throw new Error(`Router key "${key}" must start with a letter or _ and contain no dots`);
122
+ const node = nativeNode(value);
123
+ if (node === void 0)
124
+ throw new Error(`Router key "${key}" must be a query, mutation or router`);
125
+ nodes[key] = node;
126
+ }
127
+ return routerDeclaration({ kind: "router", ...withMeta(meta), children: nodes });
128
+ }
129
+ var withMeta = (meta) => meta === void 0 ? {} : { meta };
130
+ var withOverrides = (overrides) => overrides === void 0 ? {} : { overrides };
131
+ var dynamicRouter = (source) => {
132
+ const meta = source.meta;
133
+ return routerDeclaration({
134
+ kind: "dynamic",
135
+ ...meta === void 0 ? {} : {
136
+ meta: () => fromPromise(async () => meta())().pipe(
137
+ Effect_exports.flatMap((options) => Schema_exports.decodeUnknownEffect(RouterMeta)(options))
138
+ )
139
+ },
140
+ list: () => fromPromise(async () => source.list())().pipe(
141
+ Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedTool)))
142
+ ),
143
+ resolve: (name) => fromPromise(async () => source.resolve(name))().pipe(
144
+ Effect_exports.map((value) => {
145
+ if (value === void 0) return void 0;
146
+ const operation = nativeOperation(value);
147
+ if (operation === void 0) throw new Error("Expected an operation declaration");
148
+ return operation;
149
+ })
150
+ )
151
+ });
152
+ };
153
+ var joinPath = (path, name) => path === "" ? name : `${path}.${name}`;
154
+ var locate = (root, name) => {
155
+ if (root?.kind === "dynamic") return { kind: "dynamic", source: root, router: "", name };
156
+ let current = root;
157
+ let path = "";
158
+ let rest = name;
159
+ while (current !== void 0) {
160
+ const dot = rest.indexOf(".");
161
+ const key = dot < 0 ? rest : rest.slice(0, dot);
162
+ const child = Object.hasOwn(current.children, key) ? current.children[key] : void 0;
163
+ if (child === void 0) return void 0;
164
+ const remaining = dot < 0 ? void 0 : rest.slice(dot + 1);
165
+ switch (child.kind) {
166
+ case "query":
167
+ case "mutation":
168
+ return remaining === void 0 ? { kind: "operation", operation: child, router: path } : void 0;
169
+ case "dynamic":
170
+ return remaining === void 0 || remaining === "" ? void 0 : { kind: "dynamic", source: child, router: joinPath(path, key), name: remaining };
171
+ case "router":
172
+ if (remaining === void 0) return void 0;
173
+ current = child;
174
+ path = joinPath(path, key);
175
+ rest = remaining;
176
+ }
177
+ }
178
+ return void 0;
179
+ };
180
+ var declaredOperations = (root, path = "") => Object.entries(root?.children ?? {}).flatMap(([key, child]) => {
181
+ const name = joinPath(path, key);
182
+ switch (child.kind) {
183
+ case "query":
184
+ case "mutation":
185
+ return [{ name, router: path, operation: child }];
186
+ case "router":
187
+ return declaredOperations(child, name);
188
+ case "dynamic":
189
+ return [];
190
+ }
191
+ });
192
+
193
+ export {
194
+ fromPromise,
195
+ toPromise,
196
+ operationDeclaration,
197
+ nativeOperation,
198
+ withApproval,
199
+ query,
200
+ mutation,
201
+ routerDeclaration,
202
+ nativeRouter,
203
+ mergeMeta,
204
+ router,
205
+ dynamicRouter,
206
+ joinPath,
207
+ locate,
208
+ declaredOperations
209
+ };
@@ -1,5 +1,7 @@
1
1
  import {
2
2
  AppDatabaseError,
3
+ DatabaseFieldReserved,
4
+ DatabaseLimitExceeded,
3
5
  DatabaseLimits,
4
6
  DatabaseOperation,
5
7
  DatabaseSchema,
@@ -8,18 +10,21 @@ import {
8
10
  Row,
9
11
  RowMetadata,
10
12
  defaultDatabaseLimits,
11
- defaultDatabaseRuntimeLimits
12
- } from "./chunk-7JXHF5IF.js";
13
+ defaultDatabaseRuntimeLimits,
14
+ reservedFieldNames
15
+ } from "./chunk-N7YDVXYJ.js";
13
16
  import {
17
+ Cause_exports,
14
18
  Clock_exports,
15
19
  Effect_exports,
16
20
  Encoding_exports,
17
21
  Schema_exports,
18
22
  Semaphore_exports
19
- } from "./chunk-2OTCEKL2.js";
23
+ } from "./chunk-CDL5PM2Q.js";
20
24
 
21
25
  // ../app-data/src/implementation/schema.ts
22
- var metadata = /* @__PURE__ */ new Set(["id", "createdAt", "updatedAt"]);
26
+ var metadata = new Set(reservedFieldNames);
27
+ var reserved = (name) => metadata.has(name);
23
28
  var indexesFor = (table) => [{ name: "by_creation", fields: [] }, ...table.indexes].map((index) => ({
24
29
  name: index.name,
25
30
  fields: [
@@ -33,23 +38,25 @@ var validScalar = (field, value) => field.kind === "number" ? typeof value === "
33
38
  return point !== void 0 && point >= 55296 && point <= 57343;
34
39
  });
35
40
  var parseDatabaseSchema = (input) => Schema_exports.decodeUnknownEffect(DatabaseSchema)(input).pipe(
41
+ Effect_exports.mapError(() => new AppDatabaseError({ reason: "schema" })),
36
42
  Effect_exports.flatMap(
37
43
  (schema) => Effect_exports.gen(function* () {
38
- for (const table of Object.values(schema)) {
39
- if (Object.keys(table.fields).some((name) => metadata.has(name)) || new Set(table.indexes.map((index) => index.name)).size !== table.indexes.length)
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)
40
48
  return yield* new AppDatabaseError({ reason: "schema" });
41
- for (const field of Object.values(table.fields)) {
42
- if ((field.kind === "id" ? field.references === void 0 : field.references !== void 0) || field.default !== void 0 && !validScalar(field, field.default) || field.references !== void 0 && !Object.hasOwn(schema, field.references))
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))
43
51
  return yield* new AppDatabaseError({ reason: "schema" });
44
52
  }
45
53
  for (const index of table.indexes)
46
- if (index.name === "by_creation" || new Set(index.fields).size !== index.fields.length || index.fields.some((name) => fieldFor(table, name) === void 0))
54
+ if (index.name === "by_creation" || new Set(index.fields).size !== index.fields.length || index.fields.some((name2) => fieldFor(table, name2) === void 0))
47
55
  return yield* new AppDatabaseError({ reason: "schema" });
48
56
  }
49
57
  return schema;
50
58
  })
51
- ),
52
- Effect_exports.mapError(() => new AppDatabaseError({ reason: "schema" }))
59
+ )
53
60
  );
54
61
  var canonicalSchema = (schema) => JSON.stringify(
55
62
  Object.fromEntries(
@@ -248,7 +255,12 @@ var decodeBody = Schema_exports.decodeUnknownEffect(Schema_exports.fromJsonStrin
248
255
  var storageError = () => new AppDatabaseError({ reason: "storage" });
249
256
  var makeSqliteDatabase = (options) => Effect_exports.gen(function* () {
250
257
  const { sql, crypto } = options;
251
- const schema = yield* parseDatabaseSchema(options.schema);
258
+ const schema = yield* parseDatabaseSchema(options.schema).pipe(
259
+ Effect_exports.catchTag(
260
+ "DatabaseFieldReserved",
261
+ () => Effect_exports.fail(new AppDatabaseError({ reason: "schema" }))
262
+ )
263
+ );
252
264
  const limits = yield* Schema_exports.decodeUnknownEffect(DatabaseLimits)(
253
265
  options.limits ?? defaultDatabaseLimits
254
266
  ).pipe(Effect_exports.mapError(() => new AppDatabaseError({ reason: "limit" })));
@@ -295,7 +307,13 @@ var makeSqliteDatabase = (options) => Effect_exports.gen(function* () {
295
307
  };
296
308
  const charge = (name, amount) => Effect_exports.suspend(() => {
297
309
  used[name] += amount;
298
- return used[name] > limits[name] ? Effect_exports.fail(new AppDatabaseError({ reason: "limit" })) : Effect_exports.void;
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;
299
317
  });
300
318
  const get = (table, id) => Effect_exports.gen(function* () {
301
319
  yield* charge("directGets", 1);
@@ -312,8 +330,13 @@ var makeSqliteDatabase = (options) => Effect_exports.gen(function* () {
312
330
  const store = (tableName, table, row) => Effect_exports.gen(function* () {
313
331
  const meta = yield* Schema_exports.decodeUnknownEffect(RowMetadata)(row);
314
332
  const body = JSON.stringify(row);
315
- if (new TextEncoder().encode(body).length > limits.valueBytes)
316
- return yield* new AppDatabaseError({ reason: "limit" });
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
+ });
317
340
  const keys = yield* Effect_exports.forEach(
318
341
  indexesFor(table),
319
342
  (index) => encodeIndexKey(
@@ -384,9 +407,14 @@ var makeSqliteDatabase = (options) => Effect_exports.gen(function* () {
384
407
  const bounds = yield* queryBounds(table, plan, limits.indexBytes);
385
408
  reads.add(tableName);
386
409
  yield* charge("scanCalls", 1);
387
- const maximum = terminal.kind === "count" ? limits.rowsRead - used.rowsRead : limits.rowsReturned - used.rowsReturned;
388
- const count = terminal.kind === "first" ? 1 : terminal.kind === "take" ? terminal.count : terminal.kind === "paginate" ? terminal.numItems : maximum;
389
- if (count > maximum) return yield* new AppDatabaseError({ reason: "limit" });
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
+ });
390
418
  if (count === 0 && terminal.kind === "take") return [];
391
419
  const query = yield* fingerprint(
392
420
  crypto,
@@ -412,7 +440,10 @@ var makeSqliteDatabase = (options) => Effect_exports.gen(function* () {
412
440
  plan.order === "asc" ? sql`i.sort_key > ${position}` : sql`i.sort_key < ${position}`
413
441
  );
414
442
  const direction = plan.order === "asc" ? sql.literal("ASC") : sql.literal("DESC");
415
- const limit = terminal.kind === "first" || terminal.kind === "take" ? count : count + 1;
443
+ const limit = Math.min(
444
+ terminal.kind === "first" || terminal.kind === "take" ? count : count + 1,
445
+ remaining + 1
446
+ );
416
447
  if (terminal.kind === "count") {
417
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(
418
449
  Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(Schema_exports.Array(CountRow)))
@@ -436,7 +467,11 @@ var makeSqliteDatabase = (options) => Effect_exports.gen(function* () {
436
467
  )
437
468
  );
438
469
  if (terminal.kind === "collect" && rows.length > count)
439
- return yield* new AppDatabaseError({ reason: "limit" });
470
+ return yield* new DatabaseLimitExceeded({
471
+ limit: "rowsReturned",
472
+ maximum: limits.rowsReturned,
473
+ requested: used.rowsReturned + rows.length
474
+ });
440
475
  const page = rows.slice(0, count);
441
476
  yield* charge("rowsReturned", page.length);
442
477
  const values = yield* Effect_exports.forEach(page, (row) => decodeBody(row.body));
@@ -502,6 +537,11 @@ var makeSqliteDatabase = (options) => Effect_exports.gen(function* () {
502
537
  })
503
538
  };
504
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
+ ),
505
545
  Effect_exports.tap(
506
546
  () => gate.withPermits(1)(
507
547
  Effect_exports.suspend(() => failed === void 0 ? Effect_exports.void : Effect_exports.fail(failed))
package/js/client.js CHANGED
@@ -4,37 +4,36 @@ import {
4
4
  UiContext,
5
5
  UiDeploymentChanged,
6
6
  UiFailed
7
- } from "./chunk-3ANFZFCV.js";
7
+ } from "./chunk-IJX4CYZO.js";
8
8
  import {
9
9
  AsyncResult_exports,
10
10
  AtomRegistry_exports,
11
11
  Atom_exports,
12
12
  queryResult
13
- } from "./chunk-YDR4CPJA.js";
14
- import "./chunk-D6BKYP2L.js";
13
+ } from "./chunk-M3B3DE4K.js";
14
+ import "./chunk-PJJ24GU7.js";
15
15
  import {
16
16
  OtlpExporter_exports,
17
- TraceContext,
18
17
  externalTrace,
19
18
  pendingSpan,
20
19
  telemetryLayer,
21
20
  traceLinks
22
- } from "./chunk-OWD2YICM.js";
21
+ } from "./chunk-ODEIDRGW.js";
23
22
  import {
24
23
  FetchHttpClient_exports
25
- } from "./chunk-VFUZI3NY.js";
24
+ } from "./chunk-57RKNWL2.js";
26
25
  import {
27
26
  HttpClientError_exports
28
- } from "./chunk-W7Q5EOTS.js";
27
+ } from "./chunk-UK573G7W.js";
29
28
  import {
30
29
  decoderOf
31
- } from "./chunk-BPEFS4YF.js";
30
+ } from "./chunk-5T57N25Q.js";
32
31
  import {
33
32
  StorageName
34
- } from "./chunk-EP6AEUZO.js";
33
+ } from "./chunk-PZB6T6KU.js";
35
34
  import {
36
35
  JsonValue
37
- } from "./chunk-36DNRFZQ.js";
36
+ } from "./chunk-27F7W2LG.js";
38
37
  import {
39
38
  Cause_exports,
40
39
  Clock_exports,
@@ -52,8 +51,8 @@ import {
52
51
  Semaphore_exports,
53
52
  Stream_exports,
54
53
  Tracer_exports
55
- } from "./chunk-2OTCEKL2.js";
56
- import "./chunk-MLKGABMK.js";
54
+ } from "./chunk-CDL5PM2Q.js";
55
+ import "./chunk-CZ7CSFO4.js";
57
56
 
58
57
  // src/contracts/live.ts
59
58
  var AppQueryFailed = class extends Schema_exports.TaggedError()("AppQueryFailed", {}) {
@@ -448,21 +447,6 @@ var observeBrowserPerformance = Effect_exports.gen(function* () {
448
447
  };
449
448
  });
450
449
 
451
- // ../telemetry/src/browser-operations.ts
452
- var BrowserOperationFailure = Schema_exports.Struct({
453
- error_type: Schema_exports.Literals([
454
- "BrowserDecodeFailed",
455
- "BrowserTransportFailed",
456
- "BrowserOperationFailed"
457
- ]),
458
- trace_id: TraceContext.fields.traceId,
459
- span_id: TraceContext.fields.spanId,
460
- page_id: Schema_exports.String
461
- });
462
- var ResponseTrace = Context_exports.Reference("telemetry/ResponseTrace", {
463
- defaultValue: () => void 0
464
- });
465
-
466
450
  // ../telemetry/src/browser.ts
467
451
  var BrowserTelemetry = class extends Context_exports.Service()("executor/BrowserTelemetry") {
468
452
  };