@tailorkit/app 0.1.0-beta.29 → 0.1.0-beta.32

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 (53) hide show
  1. package/LICENSE.md +47 -174
  2. package/README.md +37 -38
  3. package/dist/chunk-7ZQPXG7O.js +34 -0
  4. package/dist/chunk-PJBDA2RU.js +415 -0
  5. package/dist/{chunk-STTKSRAI.js → chunk-UDXPIO6D.js} +267 -112
  6. package/dist/{chunk-ANTVMHDZ.js → chunk-YX3JURMG.js} +100 -59
  7. package/dist/client/connection.d.ts +11 -11
  8. package/dist/client/query-store.d.ts +2 -2
  9. package/dist/client/reference.d.ts +4 -4
  10. package/dist/client/session.d.ts +27 -4
  11. package/dist/client/tools.d.ts +11 -5
  12. package/dist/client-connection.js +4 -2
  13. package/dist/client.d.ts +2 -2
  14. package/dist/client.js +3 -3
  15. package/dist/database/definition.d.ts +1 -1
  16. package/dist/database/schema.d.ts +1 -1
  17. package/dist/errors.d.ts +1 -1
  18. package/dist/index.js +6 -6
  19. package/dist/preact.d.ts +5 -5
  20. package/dist/protocol.d.ts +23 -23
  21. package/dist/protocol.js +11 -9
  22. package/dist/routing.d.ts +4 -4
  23. package/dist/server/builder.d.ts +6 -6
  24. package/dist/server/bundle.d.ts +1 -6
  25. package/dist/server/functions.d.ts +19 -19
  26. package/dist/server/instances.d.ts +5 -4
  27. package/dist/server.d.ts +1 -1
  28. package/dist/server.js +4 -4
  29. package/dist/views.d.ts +4 -3
  30. package/package.json +34 -22
  31. package/dist/builder/client-views.d.ts +0 -16
  32. package/dist/builder/database-paths.d.ts +0 -4
  33. package/dist/builder/define-view.d.ts +0 -3
  34. package/dist/builder/drizzle.d.ts +0 -2
  35. package/dist/builder/file-routes.d.ts +0 -34
  36. package/dist/builder/generate-migrations.d.ts +0 -6
  37. package/dist/builder/index.d.ts +0 -11
  38. package/dist/builder/instances.d.ts +0 -19
  39. package/dist/builder/migrations.d.ts +0 -6
  40. package/dist/builder/schema-check.d.ts +0 -2
  41. package/dist/builder/server.d.ts +0 -6
  42. package/dist/builder/upload-manifest.d.ts +0 -20
  43. package/dist/builder.js +0 -1531
  44. package/dist/chunk-DA2TE2FW.js +0 -27
  45. package/dist/chunk-IJBQ77AH.js +0 -35
  46. package/dist/chunk-L5ECQGR7.js +0 -26
  47. package/dist/chunk-SWBQZDWT.js +0 -321
  48. package/dist/config/config.d.ts +0 -86
  49. package/dist/config/index.d.ts +0 -1
  50. package/dist/config/loader.d.ts +0 -7
  51. package/dist/config-loader.js +0 -7
  52. package/dist/config.js +0 -8
  53. package/dist/preact-version.d.ts +0 -7
@@ -1,15 +1,16 @@
1
1
  import {
2
2
  createClient,
3
3
  reference
4
- } from "./chunk-SWBQZDWT.js";
4
+ } from "./chunk-PJBDA2RU.js";
5
5
  import {
6
6
  AppError,
7
7
  appError
8
- } from "./chunk-IJBQ77AH.js";
8
+ } from "./chunk-7ZQPXG7O.js";
9
9
 
10
10
  // src/views.ts
11
11
  import { createContext, h } from "preact";
12
12
  import { useContext } from "preact/hooks";
13
+ var isFunctionValue = (value) => typeof value === "function";
13
14
  function defineView(options) {
14
15
  if (!options.slot || !options.view) {
15
16
  throw new Error(
@@ -17,12 +18,15 @@ function defineView(options) {
17
18
  );
18
19
  }
19
20
  const path = options.view;
20
- const Context2 = createContext(
21
- null
21
+ const Context2 = createContext(null);
22
+ const instances = (
23
+ /* oxlint-disable typescript/no-unsafe-type-assertion -- Generated bindings associate this view path with its context and instance schema; the adapter retains that relationship while erasing renderer generics. */
24
+ options.instances
22
25
  );
23
- const instances = options.instances;
24
- if (instances && !instances.resolver) {
25
- throw new Error("View instance resolvers must be compiled with the TailorKit app build.");
26
+ if (instances && !(instances.resolver !== void 0 && instances.resolver !== null && instances.resolver !== "")) {
27
+ throw new Error(
28
+ "View instance resolvers must be compiled with the TailorKit app build."
29
+ );
26
30
  }
27
31
  const View = (props) => {
28
32
  if (props.status !== "ready") {
@@ -35,34 +39,59 @@ function defineView(options) {
35
39
  }
36
40
  return h(
37
41
  Context2.Provider,
38
- { value: { context: props.context, instance: props.instance } },
39
- h(options.component, { key: props.instance?.key })
42
+ {
43
+ value: {
44
+ context: props.context,
45
+ instance: props.instance
46
+ }
47
+ },
48
+ h(
49
+ /* oxlint-disable typescript/no-unsafe-type-assertion -- Generated bindings associate this view path with its context and instance schema; the adapter retains that relationship while erasing renderer generics. */
50
+ options.component,
51
+ /* oxlint-enable typescript/no-unsafe-type-assertion */
52
+ {
53
+ key: props.instance?.key
54
+ }
55
+ )
40
56
  );
41
57
  };
58
+ const instanceMetadata = {};
59
+ if (instances?.resolver !== void 0 && instances?.resolver !== null && instances?.resolver !== "") {
60
+ instanceMetadata.instances = { resolver: instances.resolver };
61
+ }
42
62
  return {
63
+ ...instanceMetadata,
43
64
  component: View,
44
65
  path,
45
66
  slot: options.slot,
46
- ...instances?.resolver ? { instances: { resolver: instances.resolver } } : {},
47
67
  useContext: () => {
48
68
  const context = useContext(Context2);
49
69
  if (context === null) {
50
- throw new Error(`View context is only available while rendering "${path}".`);
70
+ throw new Error(
71
+ `View context is only available while rendering "${path}".`
72
+ );
51
73
  }
52
74
  return context.context;
53
75
  },
54
76
  useInstance: () => {
55
77
  const value = useContext(Context2);
56
- if (!value?.instance)
78
+ if (!value?.instance) {
57
79
  throw new Error(
58
80
  `View instance is only available while rendering an instance of "${path}".`
59
81
  );
60
- return value.instance;
82
+ }
83
+ return (
84
+ /* oxlint-disable typescript/no-unsafe-type-assertion -- Generated bindings associate this view path with its context and instance schema; the adapter retains that relationship while erasing renderer generics. */
85
+ value.instance
86
+ );
61
87
  }
62
88
  };
63
89
  }
64
90
  var componentTagPrefix = "tailorkit-";
65
- var toComponentTagName = (name) => `${componentTagPrefix}${name.replaceAll(/([a-z0-9])([A-Z])/gu, "$1-$2").replaceAll(/[\s_]+/gu, "-").toLowerCase()}`;
91
+ var toComponentTagName = (name) => `${componentTagPrefix}${name.replaceAll(
92
+ /(?<lowercase>[a-z0-9])(?<uppercase>[A-Z])/gu,
93
+ "$<lowercase>-$<uppercase>"
94
+ ).replaceAll(/[\s_]+/gu, "-").toLowerCase()}`;
66
95
  var toCallbackEventName = (name) => `tailorkitcallback${name.replaceAll(/[^A-Za-z0-9_$]/gu, "").toLowerCase()}`;
67
96
  var toEventProp = (event) => `on${event}`;
68
97
  var createRemoteComponent = (name, options = {}) => {
@@ -72,45 +101,66 @@ var createRemoteComponent = (name, options = {}) => {
72
101
  const nextProps = { ...props };
73
102
  const callbackMap = {};
74
103
  for (const [key, inputCount] of Object.entries(callbacks)) {
75
- const callback = nextProps[key];
104
+ const operation = nextProps[key];
76
105
  Reflect.deleteProperty(nextProps, key);
77
- if (typeof callback !== "function") {
106
+ if (!isFunctionValue(operation)) {
78
107
  continue;
79
108
  }
80
109
  const eventName = toCallbackEventName(key);
81
110
  callbackMap[eventName] = { callback: key, inputCount };
82
111
  nextProps[toEventProp(eventName)] = (event) => {
83
- callback(...(event.detail ?? []).slice(0, inputCount));
112
+ operation(...(event.detail ?? []).slice(0, inputCount));
84
113
  };
85
114
  }
86
115
  const serializedProps = Object.fromEntries(
87
- Object.entries(nextProps).filter(([, value]) => typeof value !== "function")
116
+ Object.entries(nextProps).filter(([, value]) => !isFunctionValue(value))
88
117
  );
89
118
  nextProps["data-tailorkit-props"] = JSON.stringify(serializedProps);
90
119
  if (Object.keys(callbackMap).length > 0) {
91
120
  nextProps["data-tailorkit-callbacks"] = JSON.stringify(callbackMap);
92
121
  }
93
- return h(tagName, nextProps, options.children ? children : void 0);
122
+ return h(
123
+ tagName,
124
+ nextProps,
125
+ options.children === true ? children : void 0
126
+ );
94
127
  };
95
128
  };
96
129
 
97
130
  // src/preact.ts
98
- import { atom as atom2, computed } from "nanostores";
99
131
  import { useStore } from "@nanostores/preact";
132
+ import { atom as atom2, computed } from "nanostores";
100
133
  import { createContext as createContext2, h as h2 } from "preact";
101
- import { useCallback, useContext as useContext2, useEffect, useLayoutEffect, useMemo, useRef } from "preact/hooks";
134
+ import {
135
+ useCallback,
136
+ useContext as useContext2,
137
+ useEffect,
138
+ useLayoutEffect,
139
+ useMemo,
140
+ useRef
141
+ } from "preact/hooks";
102
142
 
103
143
  // src/client/query-store.ts
104
144
  import { atom } from "nanostores";
105
- var pendingQuery = { data: void 0, error: null, status: "pending" };
106
- function serializeInput(input) {
107
- return JSON.stringify({ input, defined: input !== void 0 }, (_key, value) => {
108
- if (value && typeof value === "object" && !Array.isArray(value)) {
109
- return Object.fromEntries(Object.entries(value).toSorted(([a], [b]) => a.localeCompare(b)));
145
+ var isObjectValue = (value) => typeof value === "object" && value !== null;
146
+ var pendingQuery = {
147
+ data: void 0,
148
+ error: null,
149
+ status: "pending"
150
+ };
151
+ var serializeInput = (input) => JSON.stringify(
152
+ { defined: input !== void 0, input },
153
+ // Native JSON serialization supplies arbitrary values; this boundary only normalizes object key order.
154
+ // oxlint-disable-next-line anti-slop/no-unknown-parameters -- These are serializer inputs, not unparsed domain-handler arguments.
155
+ (_key, value) => {
156
+ if (isObjectValue(value) && !Array.isArray(value)) {
157
+ return Object.fromEntries(
158
+ Object.entries(value).toSorted(([a], [b]) => a.localeCompare(b))
159
+ );
110
160
  }
111
161
  return value;
112
- });
113
- }
162
+ }
163
+ );
114
164
  var QueryStore = class {
115
165
  state = atom(/* @__PURE__ */ new Map());
116
166
  entries = /* @__PURE__ */ new Map();
@@ -143,14 +193,24 @@ var QueryStore = class {
143
193
  if (this.disposed || this.entries.get(key) !== current) {
144
194
  return;
145
195
  }
146
- publish({ data: this.state.get().get(key)?.data, error, status: "error" });
196
+ publish({
197
+ data: (
198
+ /* oxlint-disable typescript/no-unsafe-type-assertion -- The entry is created and updated by this query reference's typed subscription; the shared cache erases its output generic. */
199
+ this.state.get().get(key)?.data
200
+ ),
201
+ /* oxlint-enable typescript/no-unsafe-type-assertion */
202
+ error,
203
+ status: "error"
204
+ });
147
205
  this.onError(error);
148
206
  };
149
207
  try {
150
208
  current.stop = this.client.subscribe(
151
209
  ref,
152
210
  input,
153
- (data) => publish({ data, error: null, status: "success" }),
211
+ (data) => {
212
+ publish({ data, error: null, status: "success" });
213
+ },
154
214
  { onError }
155
215
  );
156
216
  } catch (error) {
@@ -195,69 +255,100 @@ var QueryStore = class {
195
255
 
196
256
  // src/preact.ts
197
257
  var Context = createContext2(null);
198
- function ClientProvider({ children, client, onError }) {
258
+ var ClientProvider = ({
259
+ children,
260
+ client,
261
+ onError
262
+ }) => {
199
263
  const errorHandler = useRef(onError);
200
264
  errorHandler.current = onError;
201
265
  const store = useMemo(
202
- () => new QueryStore(client ?? createClient(), !client, (error) => errorHandler.current?.(error)),
266
+ () => new QueryStore(
267
+ client ?? createClient(),
268
+ !client,
269
+ (error) => errorHandler.current?.(error)
270
+ ),
203
271
  [client]
204
272
  );
205
- useLayoutEffect(() => () => store.dispose(), [store]);
273
+ useLayoutEffect(
274
+ () => () => {
275
+ store.dispose();
276
+ },
277
+ [store]
278
+ );
206
279
  return h2(Context.Provider, { value: store }, children);
207
- }
208
- function useQueryStore() {
280
+ };
281
+ var useQueryStore = () => {
209
282
  const store = useContext2(Context);
210
283
  if (!store) {
211
- throw new Error("TailorKit backend hooks require a ClientProvider at the app root.");
284
+ throw new Error(
285
+ "TailorKit backend hooks require a ClientProvider at the app root."
286
+ );
212
287
  }
213
288
  return store;
214
- }
215
- function useQuery(ref, ...[input, options]) {
289
+ };
290
+ var useQuery = (ref, ...[input, options]) => {
216
291
  const store = useQueryStore();
217
292
  const enabled = options?.enabled ?? true;
218
- const name = ref.name;
293
+ const { name } = ref;
219
294
  const serialized = serializeInput(input);
220
295
  const key = `${name}\0${serialized}`;
221
- const stableInput = useMemo(() => JSON.parse(serialized).input, [serialized]);
222
- const stableReference = useMemo(() => reference(name, "query"), [name]);
296
+ const stableInput = useMemo(
297
+ () => (
298
+ /* oxlint-disable typescript/no-unsafe-type-assertion -- serializeInput produced serialized from this reference's own input; this parses local transport-normalized input rather than external JSON. */
299
+ JSON.parse(serialized).input
300
+ ),
301
+ [serialized]
302
+ );
303
+ const stableReference = useMemo(
304
+ () => reference(name, "query"),
305
+ [name]
306
+ );
223
307
  const query = useMemo(
224
308
  () => computed(
225
309
  store.state,
226
- (queries) => enabled ? queries.get(key) ?? pendingQuery : pendingQuery
310
+ (queries) => (
311
+ /* oxlint-disable typescript/no-unsafe-type-assertion -- This cache key identifies the same reference and serialized input, so its state is populated only by that reference's O-typed subscription. */
312
+ enabled ? queries.get(key) ?? pendingQuery : pendingQuery
313
+ )
314
+ /* oxlint-enable typescript/no-unsafe-type-assertion */
227
315
  ),
228
316
  [store, key, enabled]
229
317
  );
230
318
  const state = useStore(query);
231
- useEffect(() => {
232
- if (enabled) {
233
- return store.watch(key, stableReference, stableInput);
234
- }
235
- }, [store, key, enabled, stableInput, stableReference]);
319
+ useEffect(
320
+ () => enabled ? store.watch(key, stableReference, stableInput) : void 0,
321
+ [store, key, enabled, stableInput, stableReference]
322
+ );
236
323
  return {
237
324
  ...state,
238
- isPending: state.status === "pending",
325
+ isError: state.status === "error",
239
326
  isLoading: enabled && state.status === "pending",
240
- isSuccess: state.status === "success",
241
- isError: state.status === "error"
327
+ isPending: state.status === "pending",
328
+ isSuccess: state.status === "success"
242
329
  };
243
- }
330
+ };
244
331
  var idleCall = { data: void 0, error: null, status: "idle" };
245
- function useCall(kind, ref, options) {
332
+ var useCall = (kind, ref, options) => {
246
333
  const store = useQueryStore();
247
- const name = ref.name;
334
+ const { name } = ref;
248
335
  const identity = useMemo(
249
336
  () => ({
250
- store,
251
- name,
252
337
  kind,
253
- state: atom2(idleCall)
338
+ name,
339
+ state: atom2(idleCall),
340
+ store
254
341
  }),
255
342
  [store, name, kind]
256
343
  );
257
344
  const state = useStore(identity.state);
258
- const current = useRef({ identity, sequence: 0, mounted: true });
345
+ const current = useRef({ identity, mounted: true, sequence: 0 });
259
346
  if (current.current.identity !== identity) {
260
- current.current = { identity, sequence: current.current.sequence + 1, mounted: true };
347
+ current.current = {
348
+ identity,
349
+ mounted: true,
350
+ sequence: current.current.sequence + 1
351
+ };
261
352
  }
262
353
  const callbacks = useRef(options);
263
354
  callbacks.current = options;
@@ -270,18 +361,32 @@ function useCall(kind, ref, options) {
270
361
  }, []);
271
362
  const runAsync = useCallback(
272
363
  async (...[input]) => {
273
- const sequence = ++current.current.sequence;
364
+ current.current.sequence += 1;
365
+ const { sequence } = current.current;
274
366
  const settings = callbacks.current;
275
- const args = input;
367
+ const args = (
368
+ /* oxlint-disable typescript/no-unsafe-type-assertion -- InputArguments requires an I value unless I includes undefined; destructuring its conditional tuple loses that relationship. */
369
+ input
370
+ );
276
371
  const isCurrent = () => current.current.mounted && current.current.identity === identity && current.current.sequence === sequence;
277
372
  identity.state.set({ ...idleCall, status: "pending" });
278
373
  let data;
279
374
  try {
280
- data = kind === "mutation" ? await store.client.mutate(reference(name, "mutation"), args) : await store.client.action(reference(name, "action"), args);
375
+ data = kind === "mutation" ? await store.client.mutate(
376
+ reference(name, "mutation"),
377
+ args
378
+ ) : await store.client.action(
379
+ reference(name, "action"),
380
+ args
381
+ );
281
382
  } catch (error) {
282
383
  const failure = appError(error);
283
384
  if (isCurrent()) {
284
- identity.state.set({ data: void 0, error: failure, status: "error" });
385
+ identity.state.set({
386
+ data: void 0,
387
+ error: failure,
388
+ status: "error"
389
+ });
285
390
  settings.onError?.(failure, args);
286
391
  }
287
392
  store.onError(failure);
@@ -297,8 +402,13 @@ function useCall(kind, ref, options) {
297
402
  );
298
403
  const run = useCallback(
299
404
  (...args) => {
300
- void runAsync(...args).catch(() => {
301
- });
405
+ void (async () => {
406
+ try {
407
+ return await runAsync(...args);
408
+ } catch {
409
+ }
410
+ return void 0;
411
+ })();
302
412
  },
303
413
  [runAsync]
304
414
  );
@@ -308,74 +418,89 @@ function useCall(kind, ref, options) {
308
418
  }, [identity]);
309
419
  return {
310
420
  ...state,
421
+ isError: state.status === "error",
311
422
  isPending: state.status === "pending",
312
423
  isSuccess: state.status === "success",
313
- isError: state.status === "error",
314
424
  reset,
315
425
  run,
316
426
  runAsync
317
427
  };
318
- }
319
- function useMutation(ref, options = {}) {
428
+ };
429
+ var useMutation = (ref, options = {}) => {
320
430
  const { run, runAsync, ...state } = useCall("mutation", ref, options);
321
431
  return { ...state, mutate: run, mutateAsync: runAsync };
322
- }
323
- function useAction(ref, options = {}) {
432
+ };
433
+ var useAction = (ref, options = {}) => {
324
434
  const { run, runAsync, ...state } = useCall("action", ref, options);
325
435
  return { ...state, execute: run, executeAsync: runAsync };
326
- }
436
+ };
327
437
 
328
438
  // src/routing.ts
329
439
  import { createContext as createContext3, h as h3, render } from "preact";
330
440
  import { useContext as useContext3 } from "preact/hooks";
331
- function defineRoute(options) {
332
- if (typeof options.shellComponent !== "function") {
441
+ var isFunctionValue2 = (value) => typeof value === "function";
442
+ var isObjectValue2 = (value) => typeof value === "object" && value !== null;
443
+ var isStringValue = (value) => typeof value === "string";
444
+ var defineRoute = (options) => {
445
+ if (!isFunctionValue2(options.shellComponent)) {
333
446
  throw new TypeError("defineRoute requires a shellComponent.");
334
447
  }
335
448
  return Object.freeze({ shellComponent: options.shellComponent });
336
- }
449
+ };
337
450
  var Outlet = createContext3(void 0);
338
- function Route() {
451
+ var Route = () => {
339
452
  const children = useContext3(Outlet);
340
453
  if (children === void 0) {
341
454
  throw new Error("Route must be rendered inside a root or layout.");
342
455
  }
343
456
  return children;
344
- }
345
- function Shell({ shell, children }) {
346
- return h3(Outlet.Provider, { value: children }, h3(shell, { children }));
347
- }
348
- function shellComponent(module, root) {
349
- const definition = module.definition;
350
- if (!root && typeof definition === "function") {
457
+ };
458
+ var Shell = ({
459
+ shell,
460
+ children
461
+ }) => h3(Outlet.Provider, { value: children }, h3(shell, { children }));
462
+ var shellComponent = (module, root) => {
463
+ const { definition } = module;
464
+ if (!root && isFunctionValue2(definition)) {
351
465
  return definition;
352
466
  }
353
- if (definition && typeof definition === "object" && "shellComponent" in definition && typeof definition.shellComponent === "function") {
467
+ if (isObjectValue2(definition) && "shellComponent" in definition && isFunctionValue2(definition.shellComponent)) {
354
468
  return definition.shellComponent;
355
469
  }
356
470
  throw new TypeError(
357
471
  `${module.filename} must default-export ${root ? "defineRoute({ shellComponent })" : "a layout component or defineRoute({ shellComponent })"}.`
358
472
  );
359
- }
360
- function createFileClient(options) {
473
+ };
474
+ var createFileClient = (options) => {
361
475
  const rootShell = options.root ? shellComponent(options.root, true) : void 0;
362
- const slotShells = new Map(options.roots.map((root) => [root.slot, shellComponent(root, true)]));
476
+ const slotShells = new Map(
477
+ options.roots.map((root) => [root.slot, shellComponent(root, true)])
478
+ );
363
479
  const layouts = options.layouts.map((layout) => ({
364
480
  ...layout,
365
481
  shell: shellComponent(layout, false)
366
482
  }));
367
483
  const definitions = /* @__PURE__ */ Object.create(null);
368
484
  for (const module of options.views) {
369
- const view = module.definition;
370
- if (!view || typeof view.component !== "function" || typeof view.path !== "string" || !view.path.startsWith("/")) {
371
- throw new TypeError(`${module.filename} must default-export defineView(...).`);
485
+ const view = (
486
+ /* oxlint-disable typescript/no-unsafe-type-assertion -- The generated module registry owns these component and view declarations; the runtime adapter preserves their exported implementations. */
487
+ module.definition
488
+ );
489
+ if (!view || !isFunctionValue2(view.component) || !isStringValue(view.path) || !view.path.startsWith("/")) {
490
+ throw new TypeError(
491
+ `${module.filename} must default-export defineView(...).`
492
+ );
372
493
  }
373
494
  if (view.slot !== module.slot) {
374
495
  throw new Error(
375
496
  `${module.filename} declares slot "${view.slot}" but is in "${module.slot}".`
376
497
  );
377
498
  }
378
- const slot = definitions[module.slot] ??= /* @__PURE__ */ Object.create(null);
499
+ definitions[module.slot] ??= /* @__PURE__ */ Object.create(null);
500
+ const slot = definitions[module.slot];
501
+ if (slot === void 0) {
502
+ throw new Error("Missing initialized slot registry.");
503
+ }
379
504
  if (Object.hasOwn(slot, view.path)) {
380
505
  throw new Error(
381
506
  `Duplicate view "${view.path}" in slot "${module.slot}" (${module.filename}).`
@@ -400,54 +525,84 @@ function createFileClient(options) {
400
525
  if (!view) {
401
526
  return null;
402
527
  }
403
- let child = h3(Outlet.Provider, { value: null }, h3(view.component, props));
528
+ let child = h3(
529
+ Outlet.Provider,
530
+ { value: null },
531
+ h3(view.component, props)
532
+ );
404
533
  const matching = slotLayouts.filter(
405
534
  (layout) => layout.path === "/" || props.view === layout.path || props.view.startsWith(`${layout.path}/`)
406
535
  );
407
536
  for (const layout of matching.toReversed()) {
408
- child = h3(Shell, { key: layout.path, shell: layout.shell, children: child });
537
+ child = h3(Shell, {
538
+ children: child,
539
+ key: layout.path,
540
+ shell: layout.shell
541
+ });
409
542
  }
410
543
  const shell = slotShells.get(slot);
411
- return shell ? h3(Shell, { shell, children: child }) : child;
544
+ return shell ? h3(Shell, { children: child, shell }) : child;
412
545
  };
413
546
  slots[slot] = Object.fromEntries(
414
- Object.entries(views).map(([path, view]) => [path, { ...view, component: SlotRoute }])
547
+ Object.entries(views).map(([path, view]) => [
548
+ path,
549
+ { ...view, component: SlotRoute }
550
+ ])
415
551
  );
416
552
  }
417
- const Root = rootShell ? ({ children }) => h3(Shell, { shell: rootShell, children }) : void 0;
553
+ const Root = rootShell ? ({ children }) => h3(Shell, { children, shell: rootShell }) : void 0;
418
554
  return {
419
- $meta: { preactVersion: "11.0.0" },
555
+ $meta: { preactVersion: "11.0.1" },
420
556
  $runtime: {
421
557
  h: h3,
422
- render: (vnode, parent) => render(vnode && Root ? h3(Root, { children: vnode }) : vnode, parent)
558
+ render: (vnode, parent) => {
559
+ render(vnode && Root ? h3(Root, { children: vnode }) : vnode, parent);
560
+ }
423
561
  },
424
562
  slots
425
563
  };
426
- }
564
+ };
427
565
 
428
566
  // src/client/tools.ts
429
- function callTool(kind, path, input) {
430
- const bridge = globalThis.__tailorkitTools;
431
- if (!bridge) return Promise.reject(new AppError("UNAVAILABLE", "Tool bridge unavailable"));
432
- if (kind === "client") return bridge.client(path, input);
433
- return bridge.session(path).then((session) => executeServerTool(session, path, input));
434
- }
435
- async function executeServerTool(session, path, input, request = globalThis.fetch, signal) {
567
+ import { z } from "zod";
568
+ var executeServerTool = async (session, path, input, request = globalThis.fetch, signal) => {
436
569
  const response = await request(session.url, {
570
+ body: JSON.stringify({ input, path, requestId: crypto.randomUUID() }),
571
+ credentials: "omit",
572
+ headers: {
573
+ authorization: `Bearer ${session.token}`,
574
+ "content-type": "application/json"
575
+ },
437
576
  method: "POST",
438
577
  redirect: "error",
439
- credentials: "omit",
440
- signal,
441
- headers: { authorization: `Bearer ${session.token}`, "content-type": "application/json" },
442
- body: JSON.stringify({ path, input, requestId: crypto.randomUUID() })
578
+ signal
443
579
  });
444
- if (!response.ok)
580
+ if (!response.ok) {
445
581
  throw new AppError(
446
- response.status === 401 ? "UNAUTHORIZED" : response.status === 400 ? "BAD_REQUEST" : "UNAVAILABLE",
582
+ (() => {
583
+ if (response.status === 401) {
584
+ return "UNAUTHORIZED";
585
+ }
586
+ if (response.status === 400) {
587
+ return "BAD_REQUEST";
588
+ }
589
+ return "UNAVAILABLE";
590
+ })(),
447
591
  "Tool call failed"
448
592
  );
449
- return (await response.json()).output;
450
- }
593
+ }
594
+ return z.object({ output: z.unknown().optional() }).parse(await response.json()).output;
595
+ };
596
+ var callTool = async (kind, path, input) => {
597
+ const bridge = globalThis.__tailorkitTools;
598
+ if (!bridge) {
599
+ throw new AppError("UNAVAILABLE", "Tool bridge unavailable");
600
+ }
601
+ if (kind === "client") {
602
+ return await bridge.client(path, input);
603
+ }
604
+ return await bridge.session(path).then(async (session) => await executeServerTool(session, path, input));
605
+ };
451
606
 
452
607
  export {
453
608
  defineView,