@hitch42/applet 0.1.1-beta.17 → 0.1.1-beta.19

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 (58) hide show
  1. package/dist/_internal/client.js +5 -2
  2. package/dist/_internal/server.js +5 -3
  3. package/dist/applet.js +11 -11
  4. package/dist/{lazy-client-x0DCI98S.js → batch-_ZjAg-Kk.js} +1 -14
  5. package/dist/{build-XHoa_sJL.js → build-DkKTiIu7.js} +1 -1
  6. package/dist/build-DpkWOvd2.js +2 -0
  7. package/dist/client/hitch/client.d.ts +2 -0
  8. package/dist/client/hitch/client.js +2 -0
  9. package/dist/client/hitch/phone.d.ts +2 -0
  10. package/dist/client/hitch/phone.js +2 -0
  11. package/dist/client/hitch.d.ts +3 -0
  12. package/dist/client/hitch.js +3 -0
  13. package/dist/{react → client/react}/markdown-editor.d.ts +1 -1
  14. package/dist/client/react/markdown-editor.js +2 -0
  15. package/dist/client/react/markdown.d.ts +2 -0
  16. package/dist/client/react/markdown.js +2 -0
  17. package/dist/{react.d.ts → client/react.d.ts} +2 -2
  18. package/dist/client/react.js +3 -0
  19. package/dist/client.d.ts +3 -44
  20. package/dist/client.js +2 -19
  21. package/dist/{contract-BbOj5EB7.js → contract-BeKz1Qcs.js} +6 -1
  22. package/dist/{contract-D9wEvxGI.d.ts → contract-CJv-n1l3.d.ts} +4 -2
  23. package/dist/{deploy-Da93able.js → deploy-DODTE8ri.js} +1 -1
  24. package/dist/{generate-BV_emZgy.js → generate-8yyxKRSz.js} +25 -15
  25. package/dist/generate-Df29-UJm.js +2 -0
  26. package/dist/{headers-DkNr9MLJ.js → headers-CeRX-Xji.js} +2 -1
  27. package/dist/hitch-client--qZVa2KM.d.ts +23 -0
  28. package/dist/hitch-client-Cw-WZ_8v.js +24 -0
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.js +1 -1
  31. package/dist/{init-BGQ_bP44.js → init-DT0faD-q.js} +3 -3
  32. package/dist/lazy-client-CwIzYAoE.js +14 -0
  33. package/dist/{load-config-Dkr2VxZN.js → load-config-BYrBjPlr.js} +18 -2
  34. package/dist/{logs-DOkT5ots.js → logs-CEIikWzV.js} +1 -1
  35. package/dist/{manifest-BSUtHbu-.d.ts → manifest-BBHD_EY9.d.ts} +12 -2
  36. package/dist/{project-CCVqCCgU.js → project-CWVwic2C.js} +33 -8
  37. package/dist/query-utils-zz9pVjgp.d.ts +25 -0
  38. package/dist/{schedules-D6-3v-Az.js → schedules-B7xNl9oy.js} +1 -1
  39. package/dist/server.d.ts +7 -4
  40. package/dist/server.js +3 -2
  41. package/dist/{telephony.d.ts → use-phone-M7c_HsB7.d.ts} +1 -1
  42. package/dist/{telephony.js → use-phone-ug4B5gQp.js} +1 -1
  43. package/dist/{variables-BSFZnLxY.js → variables-DCbLJBr0.js} +1 -1
  44. package/dist/vite.d.ts +1 -1
  45. package/dist/vite.js +23 -9
  46. package/package.json +11 -18
  47. package/scaffold/.agents/skills/hitch-applets/SKILL.md +8 -2
  48. package/scaffold/.agents/skills/hitch-applets/references/files.md +2 -2
  49. package/scaffold/.agents/skills/hitch-applets/references/markdown.md +8 -6
  50. package/scaffold/.agents/skills/hitch-applets/references/records.md +3 -3
  51. package/scaffold/.github/workflows/hitch.yml +1 -1
  52. package/types/public-applet-client-hitch.d.ts +2 -0
  53. package/dist/build-ueR7XjZT.js +0 -2
  54. package/dist/generate-C9bWqdaB.js +0 -2
  55. package/dist/react/markdown-editor.js +0 -2
  56. package/dist/react/markdown.d.ts +0 -2
  57. package/dist/react/markdown.js +0 -2
  58. package/dist/react.js +0 -3
@@ -1,5 +1,5 @@
1
1
  import { i as openCacheDatabase, n as clearAppletQueryCaches, o as sweepExpiredQueryCaches, r as indexedDbPersister, t as cacheTabId } from "../query-cache-CXmAyLv3.js";
2
- import { QueryClientProvider } from "@tanstack/react-query";
2
+ import { QueryClientProvider, useIsRestoring } from "@tanstack/react-query";
3
3
  import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client";
4
4
  import { RouterProvider } from "@tanstack/react-router";
5
5
  import { createElement, useEffect } from "react";
@@ -130,6 +130,9 @@ async function appletQueryPersistence(appletCode) {
130
130
  return;
131
131
  }
132
132
  }
133
+ function RestoredRouter({ router }) {
134
+ return useIsRestoring() ? null : createElement(RouterProvider, { router });
135
+ }
133
136
  function mountApplet(router, appletCode) {
134
137
  const queryClient = router.options.context.queryClient;
135
138
  if (!queryClient) throw new Error("getRouter must provide a QueryClient via createRouter({ context: { queryClient } }).");
@@ -159,7 +162,7 @@ function mountApplet(router, appletCode) {
159
162
  console.error("Could not restore the applet query cache.");
160
163
  sweepWhenIdle();
161
164
  }
162
- }, applet) : createElement(QueryClientProvider, { client: queryClient }, applet));
165
+ }, createElement(RestoredRouter, { router })) : createElement(QueryClientProvider, { client: queryClient }, applet));
163
166
  }).catch((error) => {
164
167
  console.error("Could not initialize the applet query cache.", error);
165
168
  createRoot(root).render(createElement(QueryClientProvider, { client: queryClient }, applet));
@@ -1,4 +1,4 @@
1
- import { a as HITCH_ORG_CODE_HEADER, c as HITCH_SCHEDULE_HEADER, d as HITCH_USER_HEADER, f as HITCH_WORKFLOW_HEADER, i as HITCH_ORGANIZATION_HEADER, l as HITCH_SCHEDULE_RUN_HEADER, m as HITCH_WORKFLOW_RUN_HEADER, n as HITCH_APPLET_HEADER, o as HITCH_RELEASE_HEADER, p as HITCH_WORKFLOW_INVOCATION_HEADER, r as HITCH_APPLET_TOKEN_HEADER, u as HITCH_SESSION_HEADER } from "../headers-DkNr9MLJ.js";
1
+ import { a as HITCH_ORG_CODE_HEADER, d as HITCH_SESSION_HEADER, f as HITCH_USER_HEADER, h as HITCH_WORKFLOW_RUN_HEADER, i as HITCH_ORGANIZATION_HEADER, l as HITCH_SCHEDULE_HEADER, m as HITCH_WORKFLOW_INVOCATION_HEADER, n as HITCH_APPLET_HEADER, o as HITCH_PUBLIC_HEADER, p as HITCH_WORKFLOW_HEADER, r as HITCH_APPLET_TOKEN_HEADER, s as HITCH_RELEASE_HEADER, u as HITCH_SCHEDULE_RUN_HEADER } from "../headers-CeRX-Xji.js";
2
2
  import { a as getRequestContext, o as runWithRequestContext, r as toMilliseconds, t as MAX_DURATION_MS } from "../workflow-CTo2kZF1.js";
3
3
  import { a as errorNote, c as requestIdFrom, i as createNoteLog, r as cloudflareRequestFields, s as publishNote, t as APP_CONTEXT_CHANNEL } from "../log-context-DWznGjfz.js";
4
4
  import { a as workflowOutcomeSchema, i as workflowInvocationRequestSchema, n as runWorkflowJournal, r as journalEntrySchema, t as WorkflowFailedError } from "../workflow-engine-BOTzURKM.js";
@@ -174,11 +174,12 @@ function createWorkerEntry(server, options) {
174
174
  } : appletId !== null && token !== null ? {
175
175
  kind: "applet",
176
176
  appletId,
177
- token
177
+ token,
178
+ public: request.headers.get(HITCH_PUBLIC_HEADER) === "1"
178
179
  } : void 0;
179
180
  if (identity === void 0) return jsonError(401, "missing_identity");
180
181
  log.set({
181
- callerType: identity.kind,
182
+ callerType: identity.kind === "applet" && identity.public ? "public" : identity.kind,
182
183
  callerId: identity.kind === "user" ? `user:${identity.userId}` : `applet:${identity.appletId}`
183
184
  });
184
185
  const bindings = typeof env === "object" && env !== null ? env : {};
@@ -202,6 +203,7 @@ function createWorkerEntry(server, options) {
202
203
  requestId
203
204
  }, async () => {
204
205
  const pathname = new URL(request.url).pathname;
206
+ if (pathname.startsWith("/api/__hitch/") && identity.kind === "applet" && identity.public) return jsonError(403, "platform_identity_required");
205
207
  if (pathname === "/api/__hitch/telephony/message-received" && request.method === "POST") {
206
208
  log.set({ route: "/api/__hitch/telephony/message-received" });
207
209
  if (identity.kind !== "applet") return jsonError(403, "applet_identity_required");
package/dist/applet.js CHANGED
@@ -99,23 +99,23 @@ async function main() {
99
99
  const noLogFlags = values.run === void 0 && values.filter === void 0 && values.level === void 0 && values.limit === void 0 && values.live === void 0 && values.search === void 0 && values.since === void 0;
100
100
  const noModeFlags = values["client-only"] === void 0 && values["server-only"] === void 0;
101
101
  if (positionals.length === 1 && positionals[0] === "bootstrap" && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
102
- await (await import("./init-BGQ_bP44.js")).runBootstrap({ install: values["no-install"] !== true });
102
+ await (await import("./init-DT0faD-q.js")).runBootstrap({ install: values["no-install"] !== true });
103
103
  return;
104
104
  }
105
105
  if (positionals.length === 1 && positionals[0] === "generate" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
106
- await (await import("./generate-C9bWqdaB.js")).runGenerate();
106
+ await (await import("./generate-Df29-UJm.js")).runGenerate();
107
107
  return;
108
108
  }
109
109
  if (positionals.length === 1 && positionals[0] === "build" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
110
- await (await import("./build-ueR7XjZT.js")).runBuild();
110
+ await (await import("./build-DpkWOvd2.js")).runBuild();
111
111
  return;
112
112
  }
113
113
  if (positionals.length === 1 && positionals[0] === "deploy" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
114
- await (await import("./deploy-Da93able.js")).runDeploy({});
114
+ await (await import("./deploy-DODTE8ri.js")).runDeploy({});
115
115
  return;
116
116
  }
117
117
  if (positionals.length === 2 && positionals[0] === "init" && noModeFlags && noVariableFlags && noLogFlags) {
118
- await (await import("./init-BGQ_bP44.js")).runInit(positionals[1], {
118
+ await (await import("./init-DT0faD-q.js")).runInit(positionals[1], {
119
119
  commit: values["no-commit"] !== true,
120
120
  git: values["no-git"] !== true,
121
121
  install: values["no-install"] !== true
@@ -123,7 +123,7 @@ async function main() {
123
123
  return;
124
124
  }
125
125
  if (positionals.length === 2 && positionals[0] === "new" && noGitFlags && noVariableFlags && noLogFlags) {
126
- await (await import("./init-BGQ_bP44.js")).runNew({
126
+ await (await import("./init-DT0faD-q.js")).runNew({
127
127
  code: positionals[1],
128
128
  clientOnly: values["client-only"],
129
129
  install: values["no-install"] !== true,
@@ -132,7 +132,7 @@ async function main() {
132
132
  return;
133
133
  }
134
134
  if ((positionals.length === 1 || positionals.length === 2) && positionals[0] === "logs" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags) {
135
- await (await import("./logs-DOkT5ots.js")).runLogs({
135
+ await (await import("./logs-CEIikWzV.js")).runLogs({
136
136
  code: positionals[1],
137
137
  filter: values.filter,
138
138
  run: values.run,
@@ -145,14 +145,14 @@ async function main() {
145
145
  return;
146
146
  }
147
147
  if (positionals.length === 3 && positionals[0] === "schedules" && positionals[1] === "run" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noLogFlags && values.secret === void 0) {
148
- await (await import("./schedules-D6-3v-Az.js")).runSchedule({
148
+ await (await import("./schedules-B7xNl9oy.js")).runSchedule({
149
149
  code: positionals[2],
150
150
  yes: values.yes
151
151
  });
152
152
  return;
153
153
  }
154
154
  if ((positionals.length === 3 || positionals.length === 4) && positionals[0] === "variables" && positionals[1] === "set" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noLogFlags) {
155
- await (await import("./variables-BSFZnLxY.js")).runVariablesSet({
155
+ await (await import("./variables-DCbLJBr0.js")).runVariablesSet({
156
156
  key: positionals[2],
157
157
  secret: values.secret,
158
158
  value: positionals[3],
@@ -161,11 +161,11 @@ async function main() {
161
161
  return;
162
162
  }
163
163
  if (positionals.length === 2 && positionals[0] === "variables" && positionals[1] === "list" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
164
- await (await import("./variables-BSFZnLxY.js")).runVariablesList();
164
+ await (await import("./variables-DCbLJBr0.js")).runVariablesList();
165
165
  return;
166
166
  }
167
167
  if (positionals.length === 3 && positionals[0] === "variables" && positionals[1] === "delete" && values["no-install"] === void 0 && noModeFlags && noGitFlags && values.secret === void 0 && noLogFlags) {
168
- await (await import("./variables-BSFZnLxY.js")).runVariablesDelete({
168
+ await (await import("./variables-DCbLJBr0.js")).runVariablesDelete({
169
169
  key: positionals[2],
170
170
  yes: values.yes
171
171
  });
@@ -48,17 +48,4 @@ function withBatchRecorder(target, contract) {
48
48
  } });
49
49
  }
50
50
  //#endregion
51
- //#region src/lazy-client.ts
52
- function createLazyClientProxy(build) {
53
- let client;
54
- const at = (path) => new Proxy(() => void 0, {
55
- get: (_target, property) => at([...path, property]),
56
- apply: (_target, _thisArg, args) => {
57
- client ??= build();
58
- return path.reduce((value, property) => value[property], client)(...args);
59
- }
60
- });
61
- return at([]);
62
- }
63
- //#endregion
64
- export { withBatchRecorder as n, createLazyClientProxy as t };
51
+ export { withBatchRecorder as t };
@@ -1,4 +1,4 @@
1
- import { i as prepareAppletProjects, r as prepareAppletProject } from "./project-CCVqCCgU.js";
1
+ import { i as prepareAppletProjects, r as prepareAppletProject } from "./project-CWVwic2C.js";
2
2
  import { rm } from "node:fs/promises";
3
3
  import { resolve } from "node:path";
4
4
  import { spawn } from "node:child_process";
@@ -0,0 +1,2 @@
1
+ import { i as runBuild } from "./build-DkKTiIu7.js";
2
+ export { runBuild };
@@ -0,0 +1,2 @@
1
+ import { t as hitch } from "../../hitch-client--qZVa2KM.js";
2
+ export { hitch };
@@ -0,0 +1,2 @@
1
+ import { t as hitch } from "../../hitch-client-Cw-WZ_8v.js";
2
+ export { hitch };
@@ -0,0 +1,2 @@
1
+ import { t as usePhone } from "../../use-phone-M7c_HsB7.js";
2
+ export { usePhone };
@@ -0,0 +1,2 @@
1
+ import { t as usePhone } from "../../use-phone-ug4B5gQp.js";
2
+ export { usePhone };
@@ -0,0 +1,3 @@
1
+ import { t as hitch } from "../hitch-client--qZVa2KM.js";
2
+ import { i as createPhone, n as Phone, r as PhoneState, t as usePhone } from "../use-phone-M7c_HsB7.js";
3
+ export { type Phone, type PhoneState, createPhone, hitch, usePhone };
@@ -0,0 +1,3 @@
1
+ import { t as hitch } from "../hitch-client-Cw-WZ_8v.js";
2
+ import { n as createPhone, t as usePhone } from "../use-phone-ug4B5gQp.js";
3
+ export { createPhone, hitch, usePhone };
@@ -1,2 +1,2 @@
1
- import { n as MarkdownEditorProps, r as MarkdownEditorFiles, t as MarkdownEditor } from "../markdown-editor-BmEaBzd7.js";
1
+ import { n as MarkdownEditorProps, r as MarkdownEditorFiles, t as MarkdownEditor } from "../../markdown-editor-BmEaBzd7.js";
2
2
  export { MarkdownEditor, type MarkdownEditorFiles, MarkdownEditorProps };
@@ -0,0 +1,2 @@
1
+ import { t as MarkdownEditor } from "../../markdown-editor-C5mLHGqu.js";
2
+ export { MarkdownEditor };
@@ -0,0 +1,2 @@
1
+ import { n as MarkdownFiles, r as MarkdownProps, t as Markdown } from "../../markdown-DSHOQIOb.js";
2
+ export { Markdown, MarkdownFiles, MarkdownProps };
@@ -0,0 +1,2 @@
1
+ import { t as Markdown } from "../../markdown-CwlqzBtP.js";
2
+ export { Markdown };
@@ -1,3 +1,3 @@
1
- import { n as MarkdownFiles, r as MarkdownProps, t as Markdown } from "./markdown-DSHOQIOb.js";
2
- import { n as MarkdownEditorProps, r as MarkdownEditorFiles, t as MarkdownEditor } from "./markdown-editor-BmEaBzd7.js";
1
+ import { n as MarkdownFiles, r as MarkdownProps, t as Markdown } from "../markdown-DSHOQIOb.js";
2
+ import { n as MarkdownEditorProps, r as MarkdownEditorFiles, t as MarkdownEditor } from "../markdown-editor-BmEaBzd7.js";
3
3
  export { Markdown, MarkdownEditor, type MarkdownEditorFiles, type MarkdownEditorProps, type MarkdownFiles, type MarkdownProps };
@@ -0,0 +1,3 @@
1
+ import { t as Markdown } from "../markdown-CwlqzBtP.js";
2
+ import { t as MarkdownEditor } from "../markdown-editor-C5mLHGqu.js";
3
+ export { Markdown, MarkdownEditor };
package/dist/client.d.ts CHANGED
@@ -1,48 +1,7 @@
1
- import { d as RegisteredRouter, l as RegisteredContract, u as RegisteredManifest } from "./manifest-BSUtHbu-.js";
2
- import { t as NarrowContract } from "./contract-D9wEvxGI.js";
3
- import { t as WithBatchRecorder } from "./batch-Qa4B4-Yp.js";
4
- import { o as WithFilesUpload } from "./upload-D_kkmne_.js";
1
+ import { d as RegisteredRouter } from "./manifest-BBHD_EY9.js";
2
+ import { t as ExactRouterUtils } from "./query-utils-zz9pVjgp.js";
5
3
  import { RouterClient } from "@orpc/server";
6
- import { ContractRouterClient } from "@orpc/contract";
7
- import { NestedClient } from "@orpc/client";
8
- import { RouterUtils } from "@orpc/tanstack-query";
9
- //#region src/query-utils.d.ts
10
- type Exact<Expected, Actual> = Actual extends symbol ? Actual : Actual extends Expected ? Actual extends readonly unknown[] ? Actual : Actual extends object ? NonNullable<Expected> extends object ? { [Key in keyof Actual]: Key extends keyof NonNullable<Expected> ? Exact<NonNullable<Expected>[Key], Actual[Key]> : never; } : Actual : Actual : never;
11
- type QueryOptionsFunction<Utils> = Extract<Utils extends {
12
- queryOptions: infer Function;
13
- } ? Function : never, (...args: never[]) => unknown>;
14
- type QueryOptionsArgument<Utils> = NonNullable<Parameters<QueryOptionsFunction<Utils>>[0]>;
15
- type ExactOptions<Input, Options> = Options extends {
16
- input: infer Actual;
17
- } ? Options & {
18
- input: Exact<Input, Actual>;
19
- } : Options extends {
20
- input?: infer Actual;
21
- } ? Options & {
22
- input?: Exact<Input, Actual>;
23
- } : Options;
24
- type QueryOptionsResult<Utils, Options> = Options & Omit<ReturnType<QueryOptionsFunction<Utils>>, keyof Options>;
25
- type ExactQueryOptions<Utils, Input> = <Options extends QueryOptionsArgument<Utils> = QueryOptionsArgument<Utils>>(...rest: undefined extends Input ? [options?: ExactOptions<Input, Options>] : [options: ExactOptions<Input, Options>]) => QueryOptionsResult<Utils, Options>;
26
- type ClientTree = NestedClient<Record<never, never>>;
27
- type ExactRouterUtils<Client extends ClientTree> = Client extends ((...args: infer Arguments) => unknown) ? Omit<RouterUtils<Client>, "queryOptions"> & {
28
- queryOptions: ExactQueryOptions<RouterUtils<Client>, Arguments[0]>;
29
- } : Omit<RouterUtils<Client>, keyof Client> & { [Key in keyof Client]: Client[Key] extends ClientTree ? ExactRouterUtils<Client[Key]> : never; };
30
- //#endregion
31
4
  //#region src/author/client.d.ts
32
- type AuthorContract = NarrowContract<RegisteredContract, RegisteredManifest>;
33
- type BaseHitchClient = ContractRouterClient<AuthorContract>;
34
- type AuthorHitchClient = WithBatchRecorder<BaseHitchClient>;
35
- type BaseHitchUtils = ExactRouterUtils<BaseHitchClient>;
36
- type AuthorHitchUtils = AuthorHitchClient extends {
37
- batch: infer Batch;
38
- } ? BaseHitchUtils extends {
39
- batch: infer BatchUtils;
40
- } ? Omit<BaseHitchUtils, "batch"> & {
41
- batch: Omit<BatchUtils, "call"> & {
42
- call: Batch;
43
- };
44
- } : BaseHitchUtils : BaseHitchUtils;
45
- declare const hitch: WithFilesUpload<AuthorHitchUtils>;
46
5
  declare const api: ExactRouterUtils<RouterClient<RegisteredRouter>>;
47
6
  //#endregion
48
- export { api, hitch };
7
+ export { api };
package/dist/client.js CHANGED
@@ -1,17 +1,7 @@
1
- import { n as withFilesUpload, r as getRegisteredHitchContract } from "./upload-DRbVhuDm.js";
2
- import { n as withBatchRecorder, t as createLazyClientProxy } from "./lazy-client-x0DCI98S.js";
1
+ import { t as createLazyClientProxy } from "./lazy-client-CwIzYAoE.js";
3
2
  import { createORPCClient } from "@orpc/client";
4
- import { OpenAPILink } from "@orpc/openapi-client/fetch";
5
3
  import { createTanstackQueryUtils } from "@orpc/tanstack-query";
6
4
  import { RPCLink } from "@orpc/client/fetch";
7
- //#region src/hitch/browser.ts
8
- function createHitchClient(contract) {
9
- return createLazyClientProxy(() => createORPCClient(new OpenAPILink(contract, {
10
- url: `${location.origin}/api`,
11
- fetch: (request, init) => globalThis.fetch(request, init)
12
- })));
13
- }
14
- //#endregion
15
5
  //#region src/client.ts
16
6
  function createClient(...[options]) {
17
7
  const clientOptions = options;
@@ -26,13 +16,6 @@ function createClient(...[options]) {
26
16
  }
27
17
  //#endregion
28
18
  //#region src/author/client.ts
29
- function buildClientHitch() {
30
- const contract = getRegisteredHitchContract();
31
- if (contract === void 0) throw new Error("`hitch` is unavailable: run `applet generate` first. The framework imports your .hitch automatically at build; in plain node import your .hitch once before calling hitch.");
32
- return withBatchRecorder(createHitchClient(contract), contract);
33
- }
34
- const hitchClient = createLazyClientProxy(buildClientHitch);
35
- const hitch = withFilesUpload(createTanstackQueryUtils(hitchClient), () => hitchClient.files);
36
19
  const api = createTanstackQueryUtils(createClient());
37
20
  //#endregion
38
- export { api, hitch };
21
+ export { api };
@@ -17,7 +17,12 @@ function pruneContract(contract, manifest) {
17
17
  }
18
18
  return [manifestObject.code, pruned];
19
19
  }));
20
- return Object.assign({}, contract, { records });
20
+ const platform = Object.assign({}, contract);
21
+ if (manifest.public === true) {
22
+ delete platform.email;
23
+ delete platform.telephony;
24
+ }
25
+ return Object.assign(platform, { records });
21
26
  }
22
27
  //#endregion
23
28
  export { pruneContract as t };
@@ -1,4 +1,4 @@
1
- import { n as AppletManifest } from "./manifest-BSUtHbu-.js";
1
+ import { n as AppletManifest } from "./manifest-BBHD_EY9.js";
2
2
  import { AnyContractRouter } from "@orpc/contract";
3
3
  //#region src/hitch/contract.d.ts
4
4
  type ManifestObjectFor<Manifest, Code> = Manifest extends {
@@ -15,7 +15,9 @@ type Capability<ManifestObject, Key extends "canCreate" | "canDelete" | "readWri
15
15
  type NarrowProcedures<Procedures, ManifestObject> = Omit<Procedures, (true extends Capability<ManifestObject, "canCreate"> ? never : "create") | (true extends Capability<ManifestObject, "canDelete"> ? never : "delete") | (Capability<ManifestObject, "readWrite"> extends readonly [] ? "update" | "updateWhere" : never)>;
16
16
  type NarrowContract<Contract, Manifest> = Contract extends {
17
17
  records: infer Records;
18
- } ? Omit<Contract, "records"> & {
18
+ } ? Omit<Contract, "records" | (Manifest extends {
19
+ public: true;
20
+ } ? "email" | "telephony" : never)> & {
19
21
  records: { [Code in keyof Records & ManifestObjectCodes<Manifest>]: NarrowProcedures<Records[Code], ManifestObjectFor<Manifest, Code>>; };
20
22
  } : Contract;
21
23
  declare function pruneContract<const Contract extends AnyContractRouter, const Manifest extends AppletManifest>(contract: Contract, manifest: Manifest): NarrowContract<Contract, Manifest>;
@@ -1,7 +1,7 @@
1
1
  import { n as readWorkspaceConfig } from "./workspace-8yqXsvce.js";
2
2
  import { t as fetchWithOrgAuth } from "./auth-D3CrCtZq.js";
3
3
  import { a as loadGitHubActionsSources, n as githubActionsContext, r as hitchResponseError, t as fetchWithGitHubActions } from "./ci-B5-mH-YW.js";
4
- import { n as buildPreparedApplet, r as prepareWorkspaceBuild, t as buildApplet } from "./build-XHoa_sJL.js";
4
+ import { n as buildPreparedApplet, r as prepareWorkspaceBuild, t as buildApplet } from "./build-DkKTiIu7.js";
5
5
  import { createRequire } from "node:module";
6
6
  import { createHash } from "node:crypto";
7
7
  import { existsSync } from "node:fs";
@@ -1,8 +1,8 @@
1
1
  import { a as organizationInstanceUrl, c as resolveInstanceUrl } from "./store-B8N_8JIN.js";
2
2
  import { t as fetchWithOrgAuth } from "./auth-D3CrCtZq.js";
3
- import { t as loadAppletConfig } from "./load-config-Dkr2VxZN.js";
3
+ import { t as loadAppletConfig } from "./load-config-BYrBjPlr.js";
4
4
  import { i as loadGitHubActionsBuildInputs, n as githubActionsContext } from "./ci-B5-mH-YW.js";
5
- import { r as prepareAppletProject } from "./project-CCVqCCgU.js";
5
+ import { r as prepareAppletProject } from "./project-CWVwic2C.js";
6
6
  import { createRequire } from "node:module";
7
7
  import { isContractProcedure, minifyContractRouter } from "@orpc/contract";
8
8
  import { randomUUID } from "node:crypto";
@@ -308,17 +308,16 @@ function guardManifestForSpec(spec, manifest) {
308
308
  }
309
309
  //#endregion
310
310
  //#region src/typegen/register.ts
311
- function registerFile(catalog, options) {
311
+ function registerFile(catalog, options, publicApplet) {
312
312
  const catalogType = catalog === void 0 ? "type Catalog = Record<string, string>;" : `type Catalog = {
313
313
  ${Object.entries(catalog).map(([objectCode, attributeCodes]) => ` ${JSON.stringify(objectCode)}: ${attributeCodes.map((code) => JSON.stringify(code)).join(" | ") || "never"};`).join("\n")}
314
314
  };`;
315
- return `// Generated by @hitch42/applet — do not edit.
316
- import type manifest from "./manifest.gen.ts";
317
- ${options.hasServer ? "import type server from \"../src/server/main.ts\";\nimport type * as serverModule from \"../src/server/main.ts\";\n" : ""}${options.hasClient ? "import type { Route as indexRoute } from \"../src/client/routes/index.tsx\";\n" : ""}${options.hasServer ? "import type { AnyRouter } from \"@orpc/server\";\n" : ""}${options.hasClient ? "import type { AnyRoute } from \"@tanstack/react-router\";\n" : ""}${options.hasServer ? "import type { WorkflowDefinition } from \"@hitch42/applet/server\";\nimport type { TelephonyMessageReceivedEvent, EmailMessageReceivedEvent } from \"@hitch42/applet\";\n" : ""}
318
- ${catalogType}
319
-
320
- type Expect<T extends true> = T;
321
- ${options.hasServer ? `type ServerWorkflows = typeof serverModule extends {
315
+ const serverSourceImport = options.hasServer ? "import type server from \"../src/server/main.ts\";\nimport type * as serverModule from \"../src/server/main.ts\";\n" : "";
316
+ const clientSourceImport = options.hasClient ? "import type { Route as indexRoute } from \"../src/client/routes/index.tsx\";\n" : "";
317
+ const serverTypeImports = options.hasServer ? "import type { AnyRouter } from \"@orpc/server\";\n" : "";
318
+ const clientTypeImports = options.hasClient ? "import type { AnyRoute } from \"@tanstack/react-router\";\n" : "";
319
+ const workflowImport = options.hasServer ? "import type { WorkflowDefinition } from \"@hitch42/applet/server\";\nimport type { TelephonyMessageReceivedEvent, EmailMessageReceivedEvent } from \"@hitch42/applet\";\n" : "";
320
+ const serverCheck = options.hasServer ? `type ServerWorkflows = typeof serverModule extends {
322
321
  workflows: infer Workflows extends Record<string, WorkflowDefinition<any, any>>;
323
322
  }
324
323
  ? Workflows
@@ -340,10 +339,21 @@ type _SrcServerWorkflowsMustBeNamedExport = Expect<
340
339
  : false
341
340
  : true
342
341
  >;
343
- ` : ""}${options.hasClient ? `type _SrcClientRoutesIndexMustExportARoute = Expect<
342
+ ` : "";
343
+ const clientCheck = options.hasClient ? `type _SrcClientRoutesIndexMustExportARoute = Expect<
344
344
  typeof indexRoute extends AnyRoute ? true : false
345
345
  >;
346
- ` : ""}
346
+ ` : "";
347
+ return `// Generated by @hitch42/applet — do not edit.
348
+ import type manifest from "./manifest.gen.ts";
349
+ ${serverSourceImport}${clientSourceImport}${serverTypeImports}${clientTypeImports}${workflowImport}
350
+ ${catalogType}
351
+
352
+ type Expect<T extends true> = T;
353
+ ${serverCheck}${publicApplet && options.hasServer ? `type _PublicAppletsCannotDefineWorkflows = Expect<keyof ServerWorkflows extends never ? true : false>;
354
+ type _PublicAppletsCannotHandleEmail = Expect<"email" extends keyof typeof server ? false : true>;
355
+ type _PublicAppletsCannotHandleTelephony = Expect<"telephony" extends keyof typeof server ? false : true>;
356
+ ` : ""}${clientCheck}
347
357
  declare module "@hitch42/applet" {
348
358
  interface HitchRegister {
349
359
  catalog: Catalog;
@@ -354,12 +364,12 @@ ${options.hasServer ? ` router: (typeof server)["router"];
354
364
  }
355
365
  `;
356
366
  }
357
- async function writeRegisterDeclaration(outDir, catalog) {
367
+ async function writeRegisterDeclaration(outDir, catalog, publicApplet = false) {
358
368
  await mkdir(resolve(outDir), { recursive: true });
359
369
  await writeFile(resolve(outDir, "register.ts"), registerFile(catalog, {
360
370
  hasClient: existsSync(resolve(outDir, "../src/client/routes/index.tsx")),
361
371
  hasServer: existsSync(resolve(outDir, "../src/server/main.ts"))
362
- }));
372
+ }, publicApplet));
363
373
  }
364
374
  //#endregion
365
375
  //#region src/typegen/generate.ts
@@ -480,7 +490,7 @@ async function writeContractFiles(outDir, manifest, spec) {
480
490
  const preparedSpec = prepareRecordSpec(spec, manifest);
481
491
  await generateContract(preparedSpec, outDir);
482
492
  await writeManifestGen(outDir, manifest);
483
- await writeRegisterDeclaration(outDir, catalog);
493
+ await writeRegisterDeclaration(outDir, catalog, manifest.public === true);
484
494
  const hasBatch = Object.hasOwn(preparedSpec.paths, "/v1/batch");
485
495
  await writeFile(resolve(outDir, "index.ts"), `// Generated by applet generate — do not edit.
486
496
  import { emailContract, filesContract as files, meContract as me, pruneContract, registerHitchContract, teamsContract as teams, telephonyContract as telephony } from "@hitch42/applet";
@@ -0,0 +1,2 @@
1
+ import { r as runGenerate } from "./generate-8yyxKRSz.js";
2
+ export { runGenerate };
@@ -4,6 +4,7 @@ const HITCH_SESSION_HEADER = "x-hitch-session";
4
4
  const HITCH_APPLET_HEADER = "x-hitch-applet";
5
5
  const HITCH_APPLET_CODE_HEADER = "x-hitch-applet-code";
6
6
  const HITCH_APPLET_TOKEN_HEADER = "x-hitch-applet-token";
7
+ const HITCH_PUBLIC_HEADER = "x-hitch-public";
7
8
  const HITCH_SCHEDULE_RUN_HEADER = "x-hitch-schedule-run";
8
9
  const HITCH_SCHEDULE_HEADER = "x-hitch-schedule";
9
10
  const HITCH_ORG_CODE_HEADER = "x-hitch-org-code";
@@ -14,4 +15,4 @@ const HITCH_WORKFLOW_RUN_HEADER = "x-hitch-workflow-run";
14
15
  const HITCH_WORKFLOW_HEADER = "x-hitch-workflow";
15
16
  const HITCH_WORKFLOW_INVOCATION_HEADER = "x-hitch-workflow-invocation";
16
17
  //#endregion
17
- export { HITCH_ORG_CODE_HEADER as a, HITCH_SCHEDULE_HEADER as c, HITCH_USER_HEADER as d, HITCH_WORKFLOW_HEADER as f, HITCH_ORGANIZATION_HEADER as i, HITCH_SCHEDULE_RUN_HEADER as l, HITCH_WORKFLOW_RUN_HEADER as m, HITCH_APPLET_HEADER as n, HITCH_RELEASE_HEADER as o, HITCH_WORKFLOW_INVOCATION_HEADER as p, HITCH_APPLET_TOKEN_HEADER as r, HITCH_REQUEST_HOST_HEADER as s, HITCH_APPLET_CODE_HEADER as t, HITCH_SESSION_HEADER as u };
18
+ export { HITCH_ORG_CODE_HEADER as a, HITCH_REQUEST_HOST_HEADER as c, HITCH_SESSION_HEADER as d, HITCH_USER_HEADER as f, HITCH_WORKFLOW_RUN_HEADER as h, HITCH_ORGANIZATION_HEADER as i, HITCH_SCHEDULE_HEADER as l, HITCH_WORKFLOW_INVOCATION_HEADER as m, HITCH_APPLET_HEADER as n, HITCH_PUBLIC_HEADER as o, HITCH_WORKFLOW_HEADER as p, HITCH_APPLET_TOKEN_HEADER as r, HITCH_RELEASE_HEADER as s, HITCH_APPLET_CODE_HEADER as t, HITCH_SCHEDULE_RUN_HEADER as u };
@@ -0,0 +1,23 @@
1
+ import { l as RegisteredContract, u as RegisteredManifest } from "./manifest-BBHD_EY9.js";
2
+ import { t as NarrowContract } from "./contract-CJv-n1l3.js";
3
+ import { t as WithBatchRecorder } from "./batch-Qa4B4-Yp.js";
4
+ import { o as WithFilesUpload } from "./upload-D_kkmne_.js";
5
+ import { t as ExactRouterUtils } from "./query-utils-zz9pVjgp.js";
6
+ import { ContractRouterClient } from "@orpc/contract";
7
+ //#region src/author/hitch-client.d.ts
8
+ type AuthorContract = NarrowContract<RegisteredContract, RegisteredManifest>;
9
+ type BaseHitchClient = ContractRouterClient<AuthorContract>;
10
+ type AuthorHitchClient = WithBatchRecorder<BaseHitchClient>;
11
+ type BaseHitchUtils = ExactRouterUtils<BaseHitchClient>;
12
+ type AuthorHitchUtils = AuthorHitchClient extends {
13
+ batch: infer Batch;
14
+ } ? BaseHitchUtils extends {
15
+ batch: infer BatchUtils;
16
+ } ? Omit<BaseHitchUtils, "batch"> & {
17
+ batch: Omit<BatchUtils, "call"> & {
18
+ call: Batch;
19
+ };
20
+ } : BaseHitchUtils : BaseHitchUtils;
21
+ declare const hitch: WithFilesUpload<AuthorHitchUtils>;
22
+ //#endregion
23
+ export { hitch as t };
@@ -0,0 +1,24 @@
1
+ import { n as withFilesUpload, r as getRegisteredHitchContract } from "./upload-DRbVhuDm.js";
2
+ import { t as withBatchRecorder } from "./batch-_ZjAg-Kk.js";
3
+ import { t as createLazyClientProxy } from "./lazy-client-CwIzYAoE.js";
4
+ import { createORPCClient } from "@orpc/client";
5
+ import { OpenAPILink } from "@orpc/openapi-client/fetch";
6
+ import { createTanstackQueryUtils } from "@orpc/tanstack-query";
7
+ //#region src/hitch/browser.ts
8
+ function createHitchClient(contract) {
9
+ return createLazyClientProxy(() => createORPCClient(new OpenAPILink(contract, {
10
+ url: `${location.origin}/api`,
11
+ fetch: (request, init) => globalThis.fetch(request, init)
12
+ })));
13
+ }
14
+ //#endregion
15
+ //#region src/author/hitch-client.ts
16
+ function buildClientHitch() {
17
+ const contract = getRegisteredHitchContract();
18
+ if (contract === void 0) throw new Error("`hitch` is unavailable: run `applet generate` first. The framework imports your .hitch automatically at build; in plain node import your .hitch once before calling hitch.");
19
+ return withBatchRecorder(createHitchClient(contract), contract);
20
+ }
21
+ const hitchClient = createLazyClientProxy(buildClientHitch);
22
+ const hitch = withFilesUpload(createTanstackQueryUtils(hitchClient), () => hitchClient.files);
23
+ //#endregion
24
+ export { hitch as t };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as AppletSourceDefinition, c as RegisteredCatalog, d as RegisteredRouter, f as RegisteredVariableKeys, h as registerHitchContract, i as AppletPackages, l as RegisteredContract, m as RegisteredWorkflows, n as AppletManifest, o as RegisteredAppletSourceDefinition, p as RegisteredVariables, r as AppletManifestObject, s as HitchRegister, t as AppletDefinition, u as RegisteredManifest } from "./manifest-BSUtHbu-.js";
2
- import { n as pruneContract, t as NarrowContract } from "./contract-D9wEvxGI.js";
1
+ import { a as AppletSourceDefinition, c as RegisteredCatalog, d as RegisteredRouter, f as RegisteredVariableKeys, h as registerHitchContract, i as AppletPackages, l as RegisteredContract, m as RegisteredWorkflows, n as AppletManifest, o as RegisteredAppletSourceDefinition, p as RegisteredVariables, r as AppletManifestObject, s as HitchRegister, t as AppletDefinition, u as RegisteredManifest } from "./manifest-BBHD_EY9.js";
2
+ import { n as pruneContract, t as NarrowContract } from "./contract-CJv-n1l3.js";
3
3
  import { a as UploadedHitchFile, c as filesContract, i as UploadProgress, n as FilesUpload, r as UploadFileOptions, s as uploadFile, t as FilesClient } from "./upload-D_kkmne_.js";
4
4
  import { a as EmailTracker, c as HitchEmailMessage, f as ListEmailTrackersOutput, g as emailContract, h as SendHitchEmailInput, i as EmailContract, l as HitchEmailThread, m as ListHitchEmailThreadsInput, n as TelephonyMessageReceivedEvent, o as HitchEmailAddress, p as ListHitchEmailMessagesInput, s as HitchEmailAttachment, t as EmailMessageReceivedEvent, u as HitchMailbox } from "./email-protocol-B9u_dh2p.js";
5
5
  import { ContractProcedure, Meta, Schema } from "@orpc/contract";
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { i as registerHitchContract, t as uploadFile } from "./upload-DRbVhuDm.js";
2
- import { t as pruneContract } from "./contract-BbOj5EB7.js";
2
+ import { t as pruneContract } from "./contract-BeKz1Qcs.js";
3
3
  import { oc, type } from "@orpc/contract";
4
4
  //#region src/hitch/email.ts
5
5
  function emailContract(appletCode) {
@@ -1,8 +1,8 @@
1
1
  import { c as resolveInstanceUrl, s as resolveAuthForOrg } from "./store-B8N_8JIN.js";
2
2
  import { n as readWorkspaceConfig } from "./workspace-8yqXsvce.js";
3
- import { r as runGenerate } from "./generate-BV_emZgy.js";
4
- import { n as loadAppletSourceDefinition, o as APPLET_CODE_PATTERN, s as ORG_CODE_PATTERN } from "./load-config-Dkr2VxZN.js";
5
- import { a as writeAppletSupport, n as loadCliManifest, o as writeWorkspaceSupport, t as assertWorkspaceCli } from "./project-CCVqCCgU.js";
3
+ import { r as runGenerate } from "./generate-8yyxKRSz.js";
4
+ import { n as loadAppletSourceDefinition, o as APPLET_CODE_PATTERN, s as ORG_CODE_PATTERN } from "./load-config-BYrBjPlr.js";
5
+ import { a as writeAppletSupport, n as loadCliManifest, o as writeWorkspaceSupport, t as assertWorkspaceCli } from "./project-CWVwic2C.js";
6
6
  import { access, cp, mkdir, readdir, writeFile } from "node:fs/promises";
7
7
  import { relative, resolve } from "node:path";
8
8
  import { spawn } from "node:child_process";
@@ -0,0 +1,14 @@
1
+ //#region src/lazy-client.ts
2
+ function createLazyClientProxy(build) {
3
+ let client;
4
+ const at = (path) => new Proxy(() => void 0, {
5
+ get: (_target, property) => at([...path, property]),
6
+ apply: (_target, _thisArg, args) => {
7
+ client ??= build();
8
+ return path.reduce((value, property) => value[property], client)(...args);
9
+ }
10
+ });
11
+ return at([]);
12
+ }
13
+ //#endregion
14
+ export { createLazyClientProxy as t };
@@ -77,6 +77,7 @@ const appletManifestShape = {
77
77
  name: nameSchema,
78
78
  code: codeSchema,
79
79
  requiresChangeset: z.uuid().optional(),
80
+ public: z.boolean().optional(),
80
81
  telephony: z.strictObject({
81
82
  read: z.boolean().optional(),
82
83
  send: z.boolean().optional(),
@@ -110,17 +111,30 @@ const checkDuplicateCodes = (manifest, context) => {
110
111
  ]
111
112
  });
112
113
  };
113
- const appletManifestSchema = z.strictObject(appletManifestShape).superRefine(checkDuplicateCodes);
114
+ const checkPublicFields = (manifest, context) => {
115
+ if (!manifest.public) return;
116
+ [
117
+ "schedules",
118
+ "email",
119
+ "telephony"
120
+ ].filter((field) => manifest[field] !== void 0).forEach((field) => context.addIssue({
121
+ code: "custom",
122
+ message: `Public applets cannot declare ${field}.`,
123
+ path: [field]
124
+ }));
125
+ };
126
+ const appletManifestSchema = z.strictObject(appletManifestShape).superRefine(checkDuplicateCodes).superRefine(checkPublicFields);
114
127
  z.strictObject({
115
128
  name: appletManifestShape.name,
116
129
  code: appletManifestShape.code,
117
130
  requiresChangeset: appletManifestShape.requiresChangeset,
131
+ public: appletManifestShape.public,
118
132
  telephony: appletManifestShape.telephony,
119
133
  email: appletManifestShape.email,
120
134
  schedules: appletManifestShape.schedules,
121
135
  variables: appletManifestShape.variables,
122
136
  objects: appletManifestShape.objects
123
- }).superRefine(checkDuplicateCodes);
137
+ }).superRefine(checkDuplicateCodes).superRefine(checkPublicFields);
124
138
  const packageVersionsSchema = z.record(z.string().min(1), z.string().min(1)).readonly();
125
139
  const RESERVED_APPLET_PACKAGES = /* @__PURE__ */ new Set([
126
140
  "@fontsource-variable/geist-mono",
@@ -188,6 +202,7 @@ const appletSourceDefinitionSchema = z.strictObject({
188
202
  name: appletManifestShape.name,
189
203
  code: appletManifestShape.code,
190
204
  requiresChangeset: appletManifestShape.requiresChangeset,
205
+ public: appletManifestShape.public,
191
206
  telephony: appletManifestShape.telephony,
192
207
  email: appletManifestShape.email,
193
208
  schedules: appletManifestShape.schedules,
@@ -198,6 +213,7 @@ const appletSourceDefinitionSchema = z.strictObject({
198
213
  }).superRefine((manifest, context) => {
199
214
  checkDuplicateCodes(manifest, context);
200
215
  checkSourcePackages(manifest, context);
216
+ checkPublicFields(manifest, context);
201
217
  });
202
218
  //#endregion
203
219
  //#region src/workspace.ts
@@ -1,6 +1,6 @@
1
1
  import { n as readWorkspaceConfig } from "./workspace-8yqXsvce.js";
2
2
  import { t as fetchWithOrgAuth } from "./auth-D3CrCtZq.js";
3
- import { o as APPLET_CODE_PATTERN, r as resolveWorkspaceOrg, t as loadAppletConfig } from "./load-config-Dkr2VxZN.js";
3
+ import { o as APPLET_CODE_PATTERN, r as resolveWorkspaceOrg, t as loadAppletConfig } from "./load-config-BYrBjPlr.js";
4
4
  import { z } from "zod";
5
5
  //#region src/logs.ts
6
6
  const LOG_LEVELS = [
@@ -34,6 +34,7 @@ interface AppletManifest {
34
34
  code: string;
35
35
  /** This code needs the schema as of this changeset. */
36
36
  requiresChangeset?: string;
37
+ public?: boolean;
37
38
  telephony?: {
38
39
  read?: boolean;
39
40
  send?: boolean;
@@ -78,13 +79,22 @@ type RouterSchedulePaths<R, Prefix extends string = ""> = R extends AnyProcedure
78
79
  type RegisteredSchedulePath = HitchRegister extends {
79
80
  router: infer R extends AnyRouter;
80
81
  } ? RouterSchedulePaths<R> : string;
81
- type RegisteredAppletManifest = Omit<AppletManifest, "objects" | "schedules"> & {
82
+ type RegisteredAppletManifestFields = Omit<AppletManifest, "objects" | "schedules"> & {
82
83
  schedules?: readonly (Omit<NonNullable<AppletManifest["schedules"]>[number], "path"> & {
83
84
  path: RegisteredSchedulePath;
84
85
  })[];
85
86
  objects: readonly RegisteredAppletManifestObject[];
86
87
  };
87
- type RegisteredAppletDefinition = Omit<RegisteredAppletManifest, "org">;
88
+ type RegisteredAppletManifest = (RegisteredAppletManifestFields & {
89
+ public?: false;
90
+ }) | (Omit<RegisteredAppletManifestFields, "public" | "schedules" | "email" | "telephony"> & {
91
+ public: true;
92
+ schedules?: never;
93
+ email?: never;
94
+ telephony?: never;
95
+ });
96
+ type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
97
+ type RegisteredAppletDefinition = DistributiveOmit<RegisteredAppletManifest, "org">;
88
98
  type RegisteredAppletSourceDefinition = RegisteredAppletDefinition & AppletPackages;
89
99
  //#endregion
90
100
  export { AppletSourceDefinition as a, RegisteredCatalog as c, RegisteredRouter as d, RegisteredVariableKeys as f, registerHitchContract as h, AppletPackages as i, RegisteredContract as l, RegisteredWorkflows as m, AppletManifest as n, RegisteredAppletSourceDefinition as o, RegisteredVariables as p, AppletManifestObject as r, HitchRegister as s, AppletDefinition as t, RegisteredManifest as u };
@@ -1,6 +1,6 @@
1
1
  import { a as organizationInstanceUrl, n as DEFAULT_INSTANCE_URL } from "./store-B8N_8JIN.js";
2
2
  import { n as readWorkspaceConfig } from "./workspace-8yqXsvce.js";
3
- import { n as loadAppletSourceDefinition } from "./load-config-Dkr2VxZN.js";
3
+ import { n as loadAppletSourceDefinition } from "./load-config-BYrBjPlr.js";
4
4
  import { z } from "zod";
5
5
  import { existsSync } from "node:fs";
6
6
  import { cp, mkdir, readFile, readdir, rm, symlink, writeFile } from "node:fs/promises";
@@ -204,7 +204,7 @@ minimumReleaseAgeExclude:
204
204
  - "@hitch42/*"
205
205
  `;
206
206
  }
207
- const OXLINT_CONFIG = `{
207
+ const oxlintConfigFile = (publicOverrides = "") => `{
208
208
  "$schema": "./node_modules/oxlint/configuration_schema.json",
209
209
  "plugins": ["eslint", "typescript", "unicorn", "import", "node"],
210
210
  "options": { "typeAware": true, "typeCheck": true },
@@ -248,18 +248,42 @@ const OXLINT_CONFIG = `{
248
248
  { "assertFunctionNames": ["expect", "expect*", "assert", "assert.*", "assert*"] }
249
249
  ]
250
250
  }
251
- }
251
+ }${publicOverrides}
252
252
  ]
253
253
  }
254
254
  `;
255
+ async function oxlintConfig(root) {
256
+ const appletsRoot = resolve(root, "applets");
257
+ const applets = existsSync(appletsRoot) ? await readdir(appletsRoot, { withFileTypes: true }) : [];
258
+ const publicApplets = (await Promise.all(applets.filter((applet) => applet.isDirectory() && existsSync(resolve(appletsRoot, applet.name, "applet.manifest.ts"))).map(async (applet) => {
259
+ return (await loadAppletSourceDefinition(resolve(appletsRoot, applet.name))).public === true ? applet.name : null;
260
+ }))).filter((code) => code !== null).sort();
261
+ return oxlintConfigFile(publicApplets.map((name) => `,
262
+ {
263
+ "files": [${JSON.stringify(`applets/${name}/**`)}],
264
+ "rules": {
265
+ "eslint/no-restricted-imports": [
266
+ "error",
267
+ {
268
+ "paths": [
269
+ {
270
+ "name": "@hitch42/applet/client/hitch",
271
+ "message": "Public applets have no Hitch client SDK. Call your server procedures with api from @hitch42/applet/client."
272
+ }
273
+ ]
274
+ }
275
+ ]
276
+ }
277
+ }`).join(""));
278
+ }
255
279
  async function oxfmtConfig(root) {
256
280
  const appletsRoot = resolve(root, "applets");
257
281
  const overrides = (existsSync(appletsRoot) ? await readdir(appletsRoot) : []).filter((code) => existsSync(resolve(appletsRoot, code, "src/client/styles/globals.css"))).sort().map((code) => `
258
282
  {
259
- "files": ["applets/${code}/**"],
283
+ "files": [${JSON.stringify(`applets/${code}/**`)}],
260
284
  "options": {
261
285
  "sortTailwindcss": {
262
- "stylesheet": "applets/${code}/src/client/styles/globals.css",
286
+ "stylesheet": ${JSON.stringify(`applets/${code}/src/client/styles/globals.css`)},
263
287
  "functions": ["cn", "cva"]
264
288
  }
265
289
  }
@@ -331,6 +355,7 @@ async function writeWorkspaceSupport(root, config, cli) {
331
355
  await ensureAgentConfigs(root, config.org);
332
356
  const deployWorkflowTarget = resolve(root, ".github/workflows/hitch.yml");
333
357
  const agents = await readFile(new URL("../scaffold/AGENTS.md", import.meta.url), "utf8");
358
+ const [lintConfig, formatConfig] = await Promise.all([oxlintConfig(root), oxfmtConfig(root)]);
334
359
  await Promise.all([
335
360
  mkdir(resolve(root, ".agents/skills"), { recursive: true }),
336
361
  mkdir(resolve(root, ".claude/skills"), { recursive: true }),
@@ -346,8 +371,8 @@ async function writeWorkspaceSupport(root, config, cli) {
346
371
  writeFile(resolve(root, "pnpm-workspace.yaml"), workspaceFile(resolvedCli)),
347
372
  config.githubWorkflow === false || existsSync(deployWorkflowTarget) ? void 0 : cp(new URL("../scaffold/.github/workflows/hitch.yml", import.meta.url), deployWorkflowTarget),
348
373
  writeFile(resolve(root, ".node-version"), "24\n"),
349
- writeFile(resolve(root, ".oxlintrc.json"), OXLINT_CONFIG),
350
- oxfmtConfig(root).then((config) => writeFile(resolve(root, ".oxfmtrc.json"), config)),
374
+ writeFile(resolve(root, ".oxlintrc.json"), lintConfig),
375
+ writeFile(resolve(root, ".oxfmtrc.json"), formatConfig),
351
376
  writeGitignore(root),
352
377
  writeFile(resolve(root, "AGENTS.md"), agents)
353
378
  ]);
@@ -506,7 +531,7 @@ export default defineConfig({
506
531
  "jsx": "react-jsx",
507
532
  "types": ["vite/client", "node"],
508
533
  "paths": {
509
- "@/*": ["./src/*"]
534
+ "@/*": ["./src/*"]${definition.public === true ? ",\n \"@hitch42/applet/client/hitch\": [\"./node_modules/@hitch42/applet/types/public-applet-client-hitch.d.ts\"]" : ""}
510
535
  }
511
536
  },
512
537
  "include": [
@@ -0,0 +1,25 @@
1
+ import { NestedClient } from "@orpc/client";
2
+ import { RouterUtils } from "@orpc/tanstack-query";
3
+ //#region src/query-utils.d.ts
4
+ type Exact<Expected, Actual> = Actual extends symbol ? Actual : Actual extends Expected ? Actual extends readonly unknown[] ? Actual : Actual extends object ? NonNullable<Expected> extends object ? { [Key in keyof Actual]: Key extends keyof NonNullable<Expected> ? Exact<NonNullable<Expected>[Key], Actual[Key]> : never; } : Actual : Actual : never;
5
+ type QueryOptionsFunction<Utils> = Extract<Utils extends {
6
+ queryOptions: infer Function;
7
+ } ? Function : never, (...args: never[]) => unknown>;
8
+ type QueryOptionsArgument<Utils> = NonNullable<Parameters<QueryOptionsFunction<Utils>>[0]>;
9
+ type ExactOptions<Input, Options> = Options extends {
10
+ input: infer Actual;
11
+ } ? Options & {
12
+ input: Exact<Input, Actual>;
13
+ } : Options extends {
14
+ input?: infer Actual;
15
+ } ? Options & {
16
+ input?: Exact<Input, Actual>;
17
+ } : Options;
18
+ type QueryOptionsResult<Utils, Options> = Options & Omit<ReturnType<QueryOptionsFunction<Utils>>, keyof Options>;
19
+ type ExactQueryOptions<Utils, Input> = <Options extends QueryOptionsArgument<Utils> = QueryOptionsArgument<Utils>>(...rest: undefined extends Input ? [options?: ExactOptions<Input, Options>] : [options: ExactOptions<Input, Options>]) => QueryOptionsResult<Utils, Options>;
20
+ type ClientTree = NestedClient<Record<never, never>>;
21
+ type ExactRouterUtils<Client extends ClientTree> = Client extends ((...args: infer Arguments) => unknown) ? Omit<RouterUtils<Client>, "queryOptions"> & {
22
+ queryOptions: ExactQueryOptions<RouterUtils<Client>, Arguments[0]>;
23
+ } : Omit<RouterUtils<Client>, keyof Client> & { [Key in keyof Client]: Client[Key] extends ClientTree ? ExactRouterUtils<Client[Key]> : never; };
24
+ //#endregion
25
+ export { ExactRouterUtils as t };
@@ -1,4 +1,4 @@
1
- import { t as loadAppletConfig } from "./load-config-Dkr2VxZN.js";
1
+ import { t as loadAppletConfig } from "./load-config-BYrBjPlr.js";
2
2
  import { t as question } from "./prompt-ChS-grYO.js";
3
3
  import { RPCLink } from "@orpc/client/fetch";
4
4
  import { readFile } from "node:fs/promises";
package/dist/server.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as createWorkflow, i as WorkflowStep, n as WorkflowDefinition, r as WorkflowDuration } from "./workflow-DurM6Fwx.js";
2
- import { l as RegisteredContract, m as RegisteredWorkflows, p as RegisteredVariables, u as RegisteredManifest } from "./manifest-BSUtHbu-.js";
3
- import { t as NarrowContract } from "./contract-D9wEvxGI.js";
2
+ import { l as RegisteredContract, m as RegisteredWorkflows, p as RegisteredVariables, u as RegisteredManifest } from "./manifest-BBHD_EY9.js";
3
+ import { t as NarrowContract } from "./contract-CJv-n1l3.js";
4
4
  import { t as WithBatchRecorder } from "./batch-Qa4B4-Yp.js";
5
5
  import { o as WithFilesUpload } from "./upload-D_kkmne_.js";
6
6
  import { ContractRouterClient } from "@orpc/contract";
@@ -44,8 +44,11 @@ declare const log: {
44
44
  //#region src/author/server.d.ts
45
45
  type AuthorContract = NarrowContract<RegisteredContract, RegisteredManifest>;
46
46
  type AuthorHitchClient = WithBatchRecorder<ContractRouterClient<AuthorContract>>;
47
- declare const hitch: WithFilesUpload<AuthorHitchClient> & {
47
+ type AuthorHitch = WithFilesUpload<AuthorHitchClient> & (RegisteredManifest extends {
48
+ public: true;
49
+ } ? {} : {
48
50
  workflows: WorkflowsClient<RegisteredWorkflows>;
49
- };
51
+ });
52
+ declare const hitch: AuthorHitch;
50
53
  //#endregion
51
54
  export { type AppletEnv, type WorkflowDefinition, type WorkflowDuration, type WorkflowStep, createWorkflow, env, hitch, log };
package/dist/server.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { n as withFilesUpload, r as getRegisteredHitchContract } from "./upload-DRbVhuDm.js";
2
- import { t as HITCH_APPLET_CODE_HEADER } from "./headers-DkNr9MLJ.js";
2
+ import { t as HITCH_APPLET_CODE_HEADER } from "./headers-CeRX-Xji.js";
3
3
  import { a as getRequestContext, i as getIdentityBearer, n as createWorkflow, s as tryGetRequestContext } from "./workflow-CTo2kZF1.js";
4
4
  import { s as publishNote, t as APP_CONTEXT_CHANNEL } from "./log-context-DWznGjfz.js";
5
- import { n as withBatchRecorder, t as createLazyClientProxy } from "./lazy-client-x0DCI98S.js";
5
+ import { t as withBatchRecorder } from "./batch-_ZjAg-Kk.js";
6
+ import { t as createLazyClientProxy } from "./lazy-client-CwIzYAoE.js";
6
7
  import { createORPCClient } from "@orpc/client";
7
8
  import { OpenAPILink } from "@orpc/openapi-client/fetch";
8
9
  //#region src/hitch/server.ts
@@ -94,4 +94,4 @@ declare const usePhone: () => {
94
94
  active: Phone["active"];
95
95
  };
96
96
  //#endregion
97
- export { type Phone, type PhoneState, createPhone, usePhone };
97
+ export { createPhone as i, Phone as n, PhoneState as r, usePhone as t };
@@ -723,4 +723,4 @@ const usePhone = () => {
723
723
  };
724
724
  };
725
725
  //#endregion
726
- export { createPhone, usePhone };
726
+ export { createPhone as n, usePhone as t };
@@ -1,5 +1,5 @@
1
1
  import { t as fetchWithOrgAuth } from "./auth-D3CrCtZq.js";
2
- import { t as loadAppletConfig } from "./load-config-Dkr2VxZN.js";
2
+ import { t as loadAppletConfig } from "./load-config-BYrBjPlr.js";
3
3
  import { t as question } from "./prompt-ChS-grYO.js";
4
4
  import { z } from "zod";
5
5
  //#region src/variables.ts
package/dist/vite.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { o as RegisteredAppletSourceDefinition } from "./manifest-BSUtHbu-.js";
1
+ import { o as RegisteredAppletSourceDefinition } from "./manifest-BBHD_EY9.js";
2
2
  import { PluginOption } from "vite";
3
3
  //#region src/vite.d.ts
4
4
  declare function applet<const M extends RegisteredAppletSourceDefinition>(sourceDefinition: M): PluginOption[];
package/dist/vite.js CHANGED
@@ -1,10 +1,10 @@
1
- import { t as pruneContract } from "./contract-BbOj5EB7.js";
1
+ import { t as pruneContract } from "./contract-BeKz1Qcs.js";
2
2
  import { a as openQueryCacheDatabase } from "./query-cache-CXmAyLv3.js";
3
- import { d as HITCH_USER_HEADER, u as HITCH_SESSION_HEADER } from "./headers-DkNr9MLJ.js";
3
+ import { d as HITCH_SESSION_HEADER, f as HITCH_USER_HEADER } from "./headers-CeRX-Xji.js";
4
4
  import { a as workflowOutcomeSchema, n as runWorkflowJournal } from "./workflow-engine-BOTzURKM.js";
5
5
  import { a as organizationInstanceUrl, c as resolveInstanceUrl, o as rejectEnvironmentKey, r as bearerToken, s as resolveAuthForOrg } from "./store-B8N_8JIN.js";
6
- import { a as writeRegisterDeclaration, c as writeAppletRoot, d as writeServerEntry, i as syncContract, l as writeClientEntry, n as routesModuleSource, u as writeManifestGen } from "./generate-BV_emZgy.js";
7
- import { a as appletSourceDefinitionSchema, i as appletManifestSchema, o as APPLET_CODE_PATTERN, r as resolveWorkspaceOrg } from "./load-config-Dkr2VxZN.js";
6
+ import { a as writeRegisterDeclaration, c as writeAppletRoot, d as writeServerEntry, i as syncContract, l as writeClientEntry, n as routesModuleSource, u as writeManifestGen } from "./generate-8yyxKRSz.js";
7
+ import { a as appletSourceDefinitionSchema, i as appletManifestSchema, o as APPLET_CODE_PATTERN, r as resolveWorkspaceOrg } from "./load-config-BYrBjPlr.js";
8
8
  import { z } from "zod";
9
9
  import { randomUUID } from "node:crypto";
10
10
  import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
@@ -296,6 +296,18 @@ function createDevWorkflows(options) {
296
296
  };
297
297
  }
298
298
  //#endregion
299
+ //#region src/lazy-client-react.ts
300
+ const CLIENT_REACT = "@hitch42/applet/client/react";
301
+ const lazyClientReact = {
302
+ name: "hitch-lazy-client-react",
303
+ enforce: "pre",
304
+ apply: "build",
305
+ resolveId(source, importer, options) {
306
+ if (source !== CLIENT_REACT || options.kind !== "dynamic-import") return;
307
+ return this.resolve(`${CLIENT_REACT}?lazy`, importer, { skipSelf: true });
308
+ }
309
+ };
310
+ //#endregion
299
311
  //#region src/hitch/me-schemas.ts
300
312
  const personSchema = z.object({
301
313
  id: z.uuid(),
@@ -560,6 +572,7 @@ function applet(sourceDefinition) {
560
572
  }
561
573
  const { dependencies: _dependencies, devDependencies: _devDependencies, ...definition } = parsedSourceDefinition.data;
562
574
  const parsedDefinition = { data: definition };
575
+ const mountPath = definition.public ? `app/${definition.code}` : definition.code;
563
576
  let appletConfig;
564
577
  let buildRootOutDir;
565
578
  let clearedOutDir = false;
@@ -577,7 +590,7 @@ function applet(sourceDefinition) {
577
590
  children: [{
578
591
  type: "physical",
579
592
  directory: ".",
580
- pathPrefix: parsedDefinition.data.code
593
+ pathPrefix: mountPath
581
594
  }]
582
595
  };
583
596
  const resolveAppletConfig = (root) => {
@@ -661,7 +674,7 @@ function applet(sourceDefinition) {
661
674
  }) : void 0,
662
675
  hasClient && !hasAuthorRoot ? writeAppletRoot(root) : void 0,
663
676
  hasServer ? writeServerEntry(root, hasHitchGen, manifest.code) : void 0,
664
- hasHitchGen ? void 0 : writeRegisterDeclaration(resolve(root, ".hitch"))
677
+ hasHitchGen ? void 0 : writeRegisterDeclaration(resolve(root, ".hitch"), void 0, manifest.public === true)
665
678
  ]);
666
679
  if (environment.command === "serve" && environment.mode !== "test" && environment.isPreview !== true) {
667
680
  const instanceUrl = await resolveInstanceUrl();
@@ -726,7 +739,7 @@ function applet(sourceDefinition) {
726
739
  if (colocated.length > 0) throw new Error(`Applet tests run only from the test folder. Move ${colocated.map((path) => `src/${path}`).join(", ")} to test/.`);
727
740
  }
728
741
  return {
729
- base: `/${manifest.code}/`,
742
+ base: `/${mountPath}/`,
730
743
  test: { include: ["test/**/*.test.{ts,tsx}"] },
731
744
  resolve: { alias: {
732
745
  "clsx/lite": "cn/lite",
@@ -764,7 +777,7 @@ function applet(sourceDefinition) {
764
777
  invoke: async (workflow, body) => {
765
778
  const address = server.httpServer?.address();
766
779
  if (address === null || address === void 0 || typeof address === "string") throw new Error("The dev server has no port.");
767
- const response = await fetch(`http://localhost:${address.port}/${manifest.code}/api/__hitch/workflows/${encodeURIComponent(workflow)}`, {
780
+ const response = await fetch(`http://localhost:${address.port}/${mountPath}/api/__hitch/workflows/${encodeURIComponent(workflow)}`, {
768
781
  method: "POST",
769
782
  headers: { "content-type": "application/json" },
770
783
  body: JSON.stringify(body)
@@ -806,7 +819,7 @@ function applet(sourceDefinition) {
806
819
  process.off("exit", removeDevServerFile);
807
820
  removeDevServerFile();
808
821
  });
809
- const mount = `/${manifest.code}`;
822
+ const mount = `/${mountPath}`;
810
823
  const apiPrefix = `${mount}/api`;
811
824
  server.middlewares.use((request, response, next) => {
812
825
  if (request.url === mount || request.url?.startsWith(`${mount}?`)) request.url = `${mount}/${request.url.slice(mount.length)}`;
@@ -923,6 +936,7 @@ function applet(sourceDefinition) {
923
936
  ...clsxFromCn,
924
937
  enforce: "pre"
925
938
  },
939
+ lazyClientReact,
926
940
  ...hasClientSource ? [
927
941
  tanstackRouter({
928
942
  generatedRouteTree: ".hitch/routeTree.gen.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hitch42/applet",
3
- "version": "0.1.1-beta.17",
3
+ "version": "0.1.1-beta.19",
4
4
  "license": "MIT",
5
5
  "bin": {
6
6
  "applet": "./dist/applet.js"
@@ -8,7 +8,8 @@
8
8
  "files": [
9
9
  "dist",
10
10
  "fonts",
11
- "scaffold"
11
+ "scaffold",
12
+ "types"
12
13
  ],
13
14
  "type": "module",
14
15
  "sideEffects": [
@@ -27,22 +28,6 @@
27
28
  "source": "./src/author/client.ts",
28
29
  "default": "./dist/client.js"
29
30
  },
30
- "./react": {
31
- "source": "./src/react/index.ts",
32
- "default": "./dist/react.js"
33
- },
34
- "./react/markdown": {
35
- "source": "./src/react/markdown.tsx",
36
- "default": "./dist/react/markdown.js"
37
- },
38
- "./react/markdown-editor": {
39
- "source": "./src/react/markdown-editor.tsx",
40
- "default": "./dist/react/markdown-editor.js"
41
- },
42
- "./telephony": {
43
- "source": "./src/telephony/index.ts",
44
- "default": "./dist/telephony.js"
45
- },
46
31
  "./vite": {
47
32
  "source": "./src/vite.ts",
48
33
  "default": "./dist/vite.js"
@@ -59,6 +44,14 @@
59
44
  "./_internal/log-context": {
60
45
  "source": "./src/server/log-context.ts",
61
46
  "default": "./dist/_internal/log-context.js"
47
+ },
48
+ "./client/hitch": {
49
+ "source": "./src/author/client-hitch.ts",
50
+ "default": "./dist/client/hitch.js"
51
+ },
52
+ "./client/react": {
53
+ "source": "./src/react/index.ts",
54
+ "default": "./dist/client/react.js"
62
55
  }
63
56
  },
64
57
  "dependencies": {
@@ -9,6 +9,12 @@ Build small applets against an organization's Hitch data. Keep each applet focus
9
9
 
10
10
  Treat each applet as an isolated microfrontend. Keep it separate from the data storage layer, and access Hitch data through the SDK.
11
11
 
12
+ ## Public applets
13
+
14
+ Set `public: true` for an applet that anonymous visitors can use. It is served at `https://{org}.hitch42.app/app/{code}`. It runs as the applet identity. Its manifest grants cap its access.
15
+
16
+ A public applet cannot use schedules, email, telephony, workflows, or `@hitch42/applet/client/hitch`. Client code calls its server procedures with `api` from `@hitch42/applet/client`.
17
+
12
18
  ## Go deeper
13
19
 
14
20
  This file holds the common rules. Read each matching reference before you edit an applet. Paths are relative to this file.
@@ -75,7 +81,7 @@ Use the client SDK unless the task needs a secret or an external service:
75
81
 
76
82
  ```ts
77
83
  import { useQuery } from "@tanstack/react-query";
78
- import { hitch } from "@hitch42/applet/client";
84
+ import { hitch } from "@hitch42/applet/client/hitch";
79
85
 
80
86
  const deals = useQuery(
81
87
  hitch.records.deals.list.queryOptions({
@@ -122,7 +128,7 @@ Do not invent fields or silence type errors with casts. Ask the user when genera
122
128
  Upload a file with one call. The SDK creates the file record and sends the bytes directly to storage:
123
129
 
124
130
  ```ts
125
- import { hitch } from "@hitch42/applet/client";
131
+ import { hitch } from "@hitch42/applet/client/hitch";
126
132
 
127
133
  const uploaded = await hitch.files.upload(file); // file is a web File
128
134
  ```
@@ -11,7 +11,7 @@ Use the file API to upload bytes, read file metadata, and link files to records.
11
11
  - A failed upload throws an `Error` and leaves no usable id. Call `upload(file)` again to retry — the abandoned row is harmless.
12
12
 
13
13
  ```ts
14
- import { hitch } from "@hitch42/applet/client";
14
+ import { hitch } from "@hitch42/applet/client/hitch";
15
15
 
16
16
  const uploaded = await hitch.files.upload(file);
17
17
  ```
@@ -34,7 +34,7 @@ Use a TanStack mutation in a React component:
34
34
 
35
35
  ```ts
36
36
  import { useMutation } from "@tanstack/react-query";
37
- import { hitch } from "@hitch42/applet/client";
37
+ import { hitch } from "@hitch42/applet/client/hitch";
38
38
 
39
39
  const upload = useMutation({
40
40
  mutationFn: (file: File) => hitch.files.upload(file),
@@ -9,8 +9,8 @@ Use the SDK components to edit and render markdown with Hitch file images.
9
9
  The editor supports GFM tables and task lists. A plain table serializes as GFM. A table with block content in a cell (for example a list) serializes as inline HTML, which the `Markdown` renderer also renders.
10
10
 
11
11
  ```tsx
12
- import { hitch } from "@hitch42/applet/client";
13
- import { MarkdownEditor } from "@hitch42/applet/react/markdown-editor";
12
+ import { hitch } from "@hitch42/applet/client/hitch";
13
+ import { MarkdownEditor } from "@hitch42/applet/client/react";
14
14
 
15
15
  <MarkdownEditor value={value} onChange={setValue} files={hitch.files} />;
16
16
  ```
@@ -31,7 +31,9 @@ The editor uses Tiptap and is large (about 166 KB gzip). Load it lazily when it
31
31
  import { lazy, Suspense } from "react";
32
32
 
33
33
  const MarkdownEditor = lazy(() =>
34
- import("@hitch42/applet/react/markdown-editor").then((m) => ({ default: m.MarkdownEditor })),
34
+ import("@hitch42/applet/client/react").then((m) => ({
35
+ default: m.MarkdownEditor,
36
+ })),
35
37
  );
36
38
 
37
39
  <Suspense fallback={<div className="min-h-32" />}>
@@ -39,15 +41,15 @@ const MarkdownEditor = lazy(() =>
39
41
  </Suspense>;
40
42
  ```
41
43
 
42
- Use the `/react/markdown-editor` path for the lazy import. A lazy import from `@hitch42/applet/react` does not split the editor out when the applet also imports `Markdown`.
44
+ The lazy import splits the editor out even when the page also imports `Markdown` statically: the `applet()` Vite plugin gives the dynamic import its own module.
43
45
 
44
46
  ## Render markdown
45
47
 
46
48
  Pass the same files surface to `Markdown`:
47
49
 
48
50
  ```tsx
49
- import { hitch } from "@hitch42/applet/client";
50
- import { Markdown } from "@hitch42/applet/react/markdown";
51
+ import { hitch } from "@hitch42/applet/client/hitch";
52
+ import { Markdown } from "@hitch42/applet/client/react";
51
53
 
52
54
  <Markdown files={hitch.files}>{value}</Markdown>;
53
55
  ```
@@ -2,7 +2,7 @@
2
2
 
3
3
  Use the generated Hitch contract as the typed data plane.
4
4
 
5
- - Import `hitch` from `@hitch42/applet/client` in client code.
5
+ - Import `hitch` from `@hitch42/applet/client/hitch` in client code. A public applet has no client `hitch`: it calls its own server procedures with `api` from `@hitch42/applet/client`.
6
6
  - Import `hitch` from `@hitch42/applet/server` in server code.
7
7
  - Read object codes, attribute codes, inputs, and outputs from the generated types.
8
8
  - Use only the target applet's `.hitch` types as schema evidence.
@@ -33,7 +33,7 @@ Use TanStack Query options from each generated procedure.
33
33
 
34
34
  ```ts
35
35
  import { useQuery } from "@tanstack/react-query";
36
- import { hitch } from "@hitch42/applet/client";
36
+ import { hitch } from "@hitch42/applet/client/hitch";
37
37
 
38
38
  const deals = useQuery(
39
39
  hitch.records.deals.query.queryOptions({
@@ -46,7 +46,7 @@ const deals = useQuery(
46
46
 
47
47
  ```ts
48
48
  import { useMutation } from "@tanstack/react-query";
49
- import { hitch } from "@hitch42/applet/client";
49
+ import { hitch } from "@hitch42/applet/client/hitch";
50
50
 
51
51
  const createDeal = useMutation(hitch.records.deals.create.mutationOptions());
52
52
 
@@ -12,4 +12,4 @@ jobs:
12
12
  contents: read
13
13
  id-token: write
14
14
  # Hitch verifies the called workflow's commit SHA from the OIDC token.
15
- uses: hitch-42/actions/.github/workflows/deploy.yml@4097528b45f7e2962eee9b67ff20a09a6c032d60
15
+ uses: hitch-42/actions/.github/workflows/deploy.yml@01e0cfa0a58c6186d678d425e96d8da330226e55
@@ -0,0 +1,2 @@
1
+ // Public applets have no Hitch client SDK. Call your server procedures with api from @hitch42/applet/client.
2
+ export {};
@@ -1,2 +0,0 @@
1
- import { i as runBuild } from "./build-XHoa_sJL.js";
2
- export { runBuild };
@@ -1,2 +0,0 @@
1
- import { r as runGenerate } from "./generate-BV_emZgy.js";
2
- export { runGenerate };
@@ -1,2 +0,0 @@
1
- import { t as MarkdownEditor } from "../markdown-editor-C5mLHGqu.js";
2
- export { MarkdownEditor };
@@ -1,2 +0,0 @@
1
- import { n as MarkdownFiles, r as MarkdownProps, t as Markdown } from "../markdown-DSHOQIOb.js";
2
- export { Markdown, MarkdownFiles, MarkdownProps };
@@ -1,2 +0,0 @@
1
- import { t as Markdown } from "../markdown-CwlqzBtP.js";
2
- export { Markdown };
package/dist/react.js DELETED
@@ -1,3 +0,0 @@
1
- import { t as Markdown } from "./markdown-CwlqzBtP.js";
2
- import { t as MarkdownEditor } from "./markdown-editor-C5mLHGqu.js";
3
- export { Markdown, MarkdownEditor };