apps 0.0.1-beta.1 → 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 (118) hide show
  1. package/README.md +65 -43
  2. package/framework-reference.json +1 -1
  3. package/js/browser-XIPJGLH2.js +65 -0
  4. package/js/{chunk-SATWJKN6.js → chunk-27F7W2LG.js} +1 -1
  5. package/js/{chunk-HDJH3RPR.js → chunk-57RKNWL2.js} +2 -2
  6. package/js/{chunk-2HHMABB6.js → chunk-5T57N25Q.js} +61 -13
  7. package/js/{chunk-6IIO4NPI.js → chunk-72JNVHPK.js} +21 -9
  8. package/js/{chunk-FW5HBOIK.js → chunk-CDL5PM2Q.js} +307 -169
  9. package/js/{chunk-X7SFGU4Q.js → chunk-CRDWFA74.js} +28 -9
  10. package/js/{chunk-G7IE6BKC.js → chunk-EPT3ZP52.js} +8 -8
  11. package/js/chunk-FL2QR3XW.js +507 -0
  12. package/js/{chunk-OHRT55C4.js → chunk-IJX4CYZO.js} +3 -6
  13. package/js/{chunk-ZTFQHGEB.js → chunk-IPI4MFSN.js} +3 -5
  14. package/js/{chunk-YEJOQEII.js → chunk-JU7VHODU.js} +1 -1
  15. package/js/chunk-KUMBKVJD.js +39 -0
  16. package/js/{chunk-EVJUVWN2.js → chunk-M3B3DE4K.js} +2 -2
  17. package/js/{chunk-ZJWDMTE3.js → chunk-MKWZPDR6.js} +3 -3
  18. package/js/{chunk-BMOIAIVR.js → chunk-N7YDVXYJ.js} +49 -1
  19. package/js/chunk-NKLWZJLE.js +172 -0
  20. package/js/{chunk-ZCAMUXSG.js → chunk-ODEIDRGW.js} +3 -4
  21. package/js/{chunk-M6ZRRIBI.js → chunk-PJJ24GU7.js} +1 -1
  22. package/js/{chunk-FZJOYIZO.js → chunk-PZB6T6KU.js} +1 -1
  23. package/js/chunk-R3EV5FTO.js +97 -0
  24. package/js/{chunk-6YBRWRK3.js → chunk-RFVIONFX.js} +43 -14
  25. package/js/{chunk-QKHR7BMF.js → chunk-UK573G7W.js} +1 -1
  26. package/js/{chunk-NCYXZN2G.js → chunk-UVL56Z6E.js} +390 -23
  27. package/js/{chunk-KOXMLKTM.js → chunk-V5KNQVCT.js} +308 -316
  28. package/js/{chunk-4LPG6RCH.js → chunk-VFZKSM3T.js} +5 -25
  29. package/js/{chunk-IHQ4ML7K.js → chunk-WLE7WX2U.js} +554 -102
  30. package/js/{chunk-RBAC33PQ.js → chunk-YXQHV65J.js} +58 -83
  31. package/js/chunk-Z5M2LQOZ.js +209 -0
  32. package/js/{chunk-PLCMJREA.js → chunk-ZQINWV4W.js} +60 -20
  33. package/js/client.js +10 -26
  34. package/js/contracts.js +70 -15
  35. package/js/effect.js +19 -19
  36. package/js/es-APDZKREY.js +40968 -0
  37. package/js/graphql.js +34 -39
  38. package/js/host.js +23 -23
  39. package/js/index.js +199 -195
  40. package/js/mcp/effect.js +21 -21
  41. package/js/mcp/stdio.js +25 -25
  42. package/js/mcp.js +60 -44
  43. package/js/openapi.js +826 -41682
  44. package/js/react.js +3 -3
  45. package/js/skills/effect.js +3 -4
  46. package/js/skills.js +53 -17
  47. package/js/storage/facet.js +4 -4
  48. package/js/ui/auth/contracts.js +8 -9
  49. package/js/ui/auth.js +16 -14
  50. package/js/ui/contracts.js +4 -4
  51. package/js/ui/serving.js +9 -8
  52. package/package.json +1 -1
  53. package/runtime.json +1 -1
  54. package/types/app-cache/src/contracts/cache.d.ts +42 -2
  55. package/types/app-cache/src/index.d.ts +59 -1
  56. package/types/app-data/src/contracts/database.d.ts +33 -6
  57. package/types/app-data/src/implementation/schema.d.ts +2 -17
  58. package/types/apps/src/contracts/app.d.ts +7 -6
  59. package/types/apps/src/contracts/cache.d.ts +4 -1
  60. package/types/apps/src/contracts/failure.d.ts +25 -0
  61. package/types/apps/src/contracts/host.d.ts +34 -679
  62. package/types/apps/src/contracts/mcp.d.ts +16 -0
  63. package/types/apps/src/contracts/openapi.d.ts +11 -1
  64. package/types/apps/src/contracts/operations.d.ts +0 -5
  65. package/types/apps/src/contracts/protocol-version.d.ts +6 -0
  66. package/types/apps/src/contracts/protocols/1.d.ts +1589 -0
  67. package/types/apps/src/contracts/protocols/2.d.ts +668 -0
  68. package/types/apps/src/contracts/protocols/3.d.ts +676 -0
  69. package/types/apps/src/contracts/protocols/4.d.ts +1229 -0
  70. package/types/apps/src/contracts/protocols/5.d.ts +1090 -0
  71. package/types/apps/src/contracts/provider.d.ts +51 -5
  72. package/types/apps/src/contracts/router.d.ts +59 -0
  73. package/types/apps/src/contracts/skills.d.ts +17 -8
  74. package/types/apps/src/contracts/storage.d.ts +3 -3
  75. package/types/apps/src/contracts/ui-auth.d.ts +6 -14
  76. package/types/apps/src/contracts/workflows.d.ts +34 -3
  77. package/types/apps/src/graphql.d.ts +1 -3
  78. package/types/apps/src/implementation/account-router.d.ts +12 -0
  79. package/types/apps/src/implementation/app.d.ts +5 -4
  80. package/types/apps/src/implementation/cache.d.ts +3 -1
  81. package/types/apps/src/implementation/catalog-cache.d.ts +9 -2
  82. package/types/apps/src/implementation/elicitation.d.ts +1 -1
  83. package/types/apps/src/implementation/failure-detail.d.ts +25 -0
  84. package/types/apps/src/implementation/graphql-catalog.d.ts +1 -4
  85. package/types/apps/src/implementation/mcp-catalog.d.ts +1 -4
  86. package/types/apps/src/implementation/mcp-client.d.ts +35 -19
  87. package/types/apps/src/implementation/mcp.d.ts +35 -19
  88. package/types/apps/src/implementation/openapi-compile.d.ts +3 -2
  89. package/types/apps/src/implementation/openapi-document.d.ts +0 -2
  90. package/types/apps/src/implementation/openapi-names.d.ts +18 -0
  91. package/types/apps/src/implementation/openapi-request.d.ts +0 -1
  92. package/types/apps/src/implementation/openapi-source.d.ts +7 -7
  93. package/types/apps/src/implementation/operations.d.ts +26 -3
  94. package/types/apps/src/implementation/protocol-operations.d.ts +3 -4
  95. package/types/apps/src/implementation/provider.d.ts +9 -4
  96. package/types/apps/src/implementation/router-catalog.d.ts +225 -0
  97. package/types/apps/src/implementation/router.d.ts +59 -0
  98. package/types/apps/src/implementation/schema.d.ts +5 -6
  99. package/types/apps/src/implementation/storage.d.ts +5 -3
  100. package/types/apps/src/implementation/swagger-client.d.ts +28 -0
  101. package/types/apps/src/implementation/ui-auth.d.ts +11 -5
  102. package/types/apps/src/implementation/ui-serving.d.ts +4 -2
  103. package/types/apps/src/implementation/webhooks.d.ts +1 -1
  104. package/types/apps/src/implementation/workflow-context.d.ts +11 -3
  105. package/types/apps/src/index.d.ts +5 -4
  106. package/types/apps/src/mcp-stdio.d.ts +2 -5
  107. package/types/apps/src/mcp.d.ts +5 -4
  108. package/types/apps/src/openapi.d.ts +6 -6
  109. package/types/apps/src/skills.d.ts +6 -3
  110. package/types/apps/src/ui-auth.d.ts +2 -2
  111. package/types/telemetry/src/browser-operations.d.ts +5 -2
  112. package/js/chunk-PZ36XMXW.js +0 -93
  113. package/js/chunk-SWPD52J7.js +0 -35
  114. package/js/chunk-TE4KO4HI.js +0 -47
  115. package/js/chunk-W7D7WVSY.js +0 -18
  116. package/types/apps/src/contracts/dynamic-tools.d.ts +0 -13
  117. package/types/apps/src/implementation/account-operations.d.ts +0 -151
  118. package/types/apps/src/implementation/dynamic-tools.d.ts +0 -8
@@ -1,78 +1,51 @@
1
1
  import {
2
- parseDatabaseSchema,
3
2
  promiseTable
4
- } from "./chunk-PLCMJREA.js";
3
+ } from "./chunk-ZQINWV4W.js";
5
4
  import {
5
+ declaredOperations,
6
6
  fromPromise,
7
- nativeOperation
8
- } from "./chunk-PZ36XMXW.js";
7
+ nativeOperation,
8
+ nativeRouter
9
+ } from "./chunk-Z5M2LQOZ.js";
9
10
  import {
10
11
  ScheduleTiming
11
- } from "./chunk-IHQ4ML7K.js";
12
+ } from "./chunk-WLE7WX2U.js";
13
+ import {
14
+ DatabaseSchema
15
+ } from "./chunk-N7YDVXYJ.js";
12
16
  import {
13
17
  decoderOf,
14
18
  isSchema,
15
19
  storageFieldOf
16
- } from "./chunk-2HHMABB6.js";
20
+ } from "./chunk-5T57N25Q.js";
17
21
  import {
18
22
  AppStorageUnavailable
19
- } from "./chunk-FZJOYIZO.js";
23
+ } from "./chunk-PZB6T6KU.js";
20
24
  import {
21
25
  JsonValue
22
- } from "./chunk-SATWJKN6.js";
26
+ } from "./chunk-27F7W2LG.js";
23
27
  import {
24
28
  Effect_exports,
25
29
  Schema_exports
26
- } from "./chunk-FW5HBOIK.js";
30
+ } from "./chunk-CDL5PM2Q.js";
27
31
 
28
- // ../app-cache/src/contracts/cache.ts
29
- var CacheError = class extends Schema_exports.TaggedError()("CacheError", {
30
- reason: Schema_exports.Literals(["unavailable", "storage", "invalid", "capacity", "timeout"])
31
- }) {
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}`;
39
+ }
32
40
  };
33
- var cacheLimits = {
34
- keyBytes: 8192,
35
- entryBytes: 2e6,
36
- batchBytes: 8e6,
37
- batchEntries: 128,
38
- totalBytes: 128e6,
39
- totalEntries: 1e5,
40
- retentionMs: 7 * 24 * 60 * 60 * 1e3,
41
- loadTimeoutMs: 9e4,
42
- leaseMs: 12e4
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
+ }
43
48
  };
44
- var Key = Schema_exports.String.check(Schema_exports.isPattern(/^[a-f0-9]{64}$/));
45
- var Time = Schema_exports.Finite.check(Schema_exports.isGreaterThanOrEqualTo(0));
46
- var CacheEntry = Schema_exports.Struct({
47
- value: Schema_exports.Json,
48
- version: Schema_exports.String,
49
- freshUntil: Time,
50
- staleUntil: Time
51
- });
52
- var CacheCommand = Schema_exports.Union([
53
- Schema_exports.Struct({ operation: Schema_exports.Literal("read"), keys: Schema_exports.Array(Key) }),
54
- Schema_exports.Struct({
55
- operation: Schema_exports.Literal("claim"),
56
- key: Key,
57
- version: Schema_exports.NullOr(Schema_exports.String)
58
- }),
59
- Schema_exports.Struct({
60
- operation: Schema_exports.Literal("publish"),
61
- key: Key,
62
- lease: Schema_exports.String,
63
- entry: CacheEntry
64
- }),
65
- Schema_exports.Struct({ operation: Schema_exports.Literal("release"), key: Key, lease: Schema_exports.String }),
66
- Schema_exports.Struct({
67
- operation: Schema_exports.Literal("write"),
68
- entries: Schema_exports.Array(Schema_exports.Struct({ key: Key, entry: CacheEntry }))
69
- }),
70
- Schema_exports.Struct({ operation: Schema_exports.Literal("invalidate"), key: Key })
71
- ]);
72
- var CacheReply = Schema_exports.Union([
73
- Schema_exports.Struct({ ok: Schema_exports.Literal(true), value: Schema_exports.Json }),
74
- Schema_exports.Struct({ ok: Schema_exports.Literal(false), error: CacheError })
75
- ]);
76
49
 
77
50
  // src/implementation/workflows.ts
78
51
  var NativeWorkflow = /* @__PURE__ */ Symbol("apps.Workflow");
@@ -97,8 +70,12 @@ var nativeWorkflow = (value) => {
97
70
  var InternalApp = /* @__PURE__ */ Symbol("apps.App");
98
71
  var isApp = (value) => typeof value === "object" && value !== null && InternalApp in value;
99
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
+ }
100
77
  function adaptDefinition(definition) {
101
- if ("tools" in definition) throw new Error("Use queries and mutations instead of tools");
78
+ rejectCatalogs(definition);
102
79
  const webhooks = definition.webhooks === void 0 ? {} : {
103
80
  webhooks: Object.fromEntries(
104
81
  Object.entries(definition.webhooks).map(([name, webhook]) => [
@@ -114,42 +91,42 @@ function adaptDefinition(definition) {
114
91
  ])
115
92
  )
116
93
  };
117
- const operations = (kind, catalog) => Object.fromEntries(
118
- Object.entries(catalog).map(([name, value]) => {
119
- const operation = nativeOperation(value);
120
- if (operation === void 0 || operation.kind !== kind)
121
- throw new Error("Invalid app data operation");
122
- return [name, operation];
123
- })
124
- );
125
94
  const workflows = definition.workflows === void 0 ? {} : {
126
95
  workflows: Object.fromEntries(
127
96
  Object.entries(definition.workflows).map(([name, value]) => {
128
- const declared = nativeWorkflow(value);
129
- if (declared === void 0) throw new Error("Invalid workflow declaration");
130
- return [name, declared];
97
+ const declared2 = nativeWorkflow(value);
98
+ if (declared2 === void 0) throw new Error("Invalid workflow declaration");
99
+ return [name, declared2];
131
100
  })
132
101
  )
133
102
  };
134
- const data = {
135
- ...definition.queries === void 0 ? {} : { queries: operations("query", definition.queries) },
136
- ...definition.mutations === void 0 ? {} : { mutations: operations("mutation", definition.mutations) }
137
- };
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
+ }
138
115
  const schedules = definition.schedules === void 0 ? {} : {
139
116
  schedules: Object.fromEntries(
140
117
  Object.entries(definition.schedules).map(([name, schedule]) => {
141
- const matches = Object.entries(definition.mutations ?? {}).filter(
142
- ([, operation]) => operation === schedule.operation
118
+ const target = nativeOperation(schedule.operation);
119
+ const match = declared.find(
120
+ ({ operation }) => operation === target && operation.kind === "mutation"
143
121
  );
144
- const match = matches[0];
145
- if (match === void 0 || matches.length !== 1)
146
- 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");
147
124
  return [
148
125
  name,
149
126
  {
150
127
  timing: Schema_exports.decodeUnknownSync(ScheduleTiming)(schedule.timing),
151
128
  input: Schema_exports.decodeUnknownSync(JsonValue)(schedule.input),
152
- tool: `mutations.${match[0]}`
129
+ tool: match.name
153
130
  }
154
131
  ];
155
132
  })
@@ -164,6 +141,7 @@ function adaptDefinition(definition) {
164
141
  };
165
142
  }
166
143
  var defineApp = (requirements, definition) => {
144
+ if (typeof definition !== "function") rejectCatalogs(definition);
167
145
  const evaluate = typeof definition === "function" ? definition : async () => definition;
168
146
  const factory = fromPromise(evaluate);
169
147
  const native = {
@@ -201,7 +179,7 @@ var serialize = (tables) => {
201
179
  }
202
180
  ])
203
181
  );
204
- return Effect_exports.runSync(parseDatabaseSchema(definitions));
182
+ return Schema_exports.decodeUnknownSync(DatabaseSchema)(definitions);
205
183
  };
206
184
  var authorDatabase = (tables, session, signal, writable) => {
207
185
  return Object.fromEntries(
@@ -251,11 +229,8 @@ var unavailableStorage = {
251
229
  };
252
230
 
253
231
  export {
254
- CacheError,
255
- cacheLimits,
256
- CacheEntry,
257
- CacheCommand,
258
- CacheReply,
232
+ ResponseStatusError,
233
+ ResponseDecodeError,
259
234
  workflow,
260
235
  isApp,
261
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-BMOIAIVR.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-FW5HBOIK.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-OHRT55C4.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-EVJUVWN2.js";
14
- import "./chunk-M6ZRRIBI.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-ZCAMUXSG.js";
21
+ } from "./chunk-ODEIDRGW.js";
23
22
  import {
24
23
  FetchHttpClient_exports
25
- } from "./chunk-HDJH3RPR.js";
24
+ } from "./chunk-57RKNWL2.js";
26
25
  import {
27
26
  HttpClientError_exports
28
- } from "./chunk-QKHR7BMF.js";
27
+ } from "./chunk-UK573G7W.js";
29
28
  import {
30
29
  decoderOf
31
- } from "./chunk-2HHMABB6.js";
30
+ } from "./chunk-5T57N25Q.js";
32
31
  import {
33
32
  StorageName
34
- } from "./chunk-FZJOYIZO.js";
33
+ } from "./chunk-PZB6T6KU.js";
35
34
  import {
36
35
  JsonValue
37
- } from "./chunk-SATWJKN6.js";
36
+ } from "./chunk-27F7W2LG.js";
38
37
  import {
39
38
  Cause_exports,
40
39
  Clock_exports,
@@ -52,7 +51,7 @@ import {
52
51
  Semaphore_exports,
53
52
  Stream_exports,
54
53
  Tracer_exports
55
- } from "./chunk-FW5HBOIK.js";
54
+ } from "./chunk-CDL5PM2Q.js";
56
55
  import "./chunk-CZ7CSFO4.js";
57
56
 
58
57
  // src/contracts/live.ts
@@ -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
  };