@tailorkit/app 0.1.0-beta.19 → 0.1.0-beta.20
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.
- package/README.md +1 -1
- package/dist/builder.js +4 -4
- package/dist/{chunk-43L6XVW6.js → chunk-RHCGWGSG.js} +22 -9
- package/dist/client.js +3 -3
- package/dist/index.js +3 -3
- package/dist/views.d.ts +34 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -94,7 +94,7 @@ Auth signing and verification use Effect v4. `issueAppTokenEffect`, `appTokenVer
|
|
|
94
94
|
|
|
95
95
|
Add `server: {}` to `tailorkit.config.ts` to build the backend from `src/server.ts`. The client builds from `src/client.ts` by default. `client.entry` and `server.entry` override these source entry points while output filenames stay the same. `tailorkit build` emits `.tailorkit/client/client.js` and `.tailorkit/server/server.js`, and copies committed Drizzle migration files into `.tailorkit/migrations/`. Intermediate server entries are created under the output root’s `tmp/` directory and removed after builds or when the watcher closes; `server/` contains the upload artifact. The server exports the application definition and embedded migrations; Cloudflare bootstrap code belongs to the runtime worker. The builder writes no backend reference source files. The browser builder rejects server implementation imports. `build.outDir` and `--out-dir` change the common output root for all artifacts; preview serves only its `client/` directory.
|
|
96
96
|
|
|
97
|
-
`tailorkit deploy`
|
|
97
|
+
`tailorkit deploy` gzips the client and private server artifacts before uploading them through platform-issued blob upload URLs. Checksums and content lengths describe the compressed bytes stored in R2. The runtime verifies and decompresses server code before loading it; client delivery serves gzip to browsers that accept it. The platform checks that decoded client bundles fit within 3 MiB before publication, and decoded delivery streams enforce the same limit. Existing uncompressed deployments remain supported. Apps need no Cloudflare credentials. R2 stores them under separate `client/` and `server/` prefixes; only client assets are public. Client-only apps continue to build without a server artifact. Watch mode watches both builds.
|
|
98
98
|
|
|
99
99
|
The legacy `app-storage` SDK, `storage` config and storage CLI commands have been removed. Use `server` config and this SDK. The host session endpoint `/backend/session` uses the existing host `authenticate` callback. The platform verifies scope access and resolves the installation and runtime URL automatically; no extra host backend configuration is required.
|
|
100
100
|
|
package/dist/builder.js
CHANGED
|
@@ -563,7 +563,7 @@ async function extractInstances(filename, source, root, includedNames) {
|
|
|
563
563
|
if (statement.type !== "ImportDeclaration" || !clientImports.has(String(statement.source.value)))
|
|
564
564
|
continue;
|
|
565
565
|
for (const s of statement.specifiers) {
|
|
566
|
-
if (s.type === "ImportSpecifier" && s.imported.type === "Identifier" && s.imported.name === "
|
|
566
|
+
if (s.type === "ImportSpecifier" && s.imported.type === "Identifier" && s.imported.name === "defineView")
|
|
567
567
|
aliases.add(s.local.name);
|
|
568
568
|
}
|
|
569
569
|
}
|
|
@@ -571,7 +571,7 @@ async function extractInstances(filename, source, root, includedNames) {
|
|
|
571
571
|
walk(program, (node, ancestors) => {
|
|
572
572
|
if (node.type !== "CallExpression" || node.callee.type !== "Identifier" || !aliases.has(node.callee.name))
|
|
573
573
|
return;
|
|
574
|
-
const options = node.arguments[
|
|
574
|
+
const options = node.arguments[0];
|
|
575
575
|
if (options?.type !== "ObjectExpression") return;
|
|
576
576
|
const instances = property(options, "instances");
|
|
577
577
|
if (!instances) return;
|
|
@@ -579,10 +579,10 @@ async function extractInstances(filename, source, root, includedNames) {
|
|
|
579
579
|
throw new Error(`${filename}: ${message}`);
|
|
580
580
|
};
|
|
581
581
|
if (ancestors.some(isFunction))
|
|
582
|
-
fail("
|
|
582
|
+
fail("defineView with instances must be declared at module scope.");
|
|
583
583
|
const owner = ancestors.findLast((n) => n.type === "VariableDeclarator");
|
|
584
584
|
const viewName = owner?.type === "VariableDeclarator" && owner.id.type === "Identifier" ? owner.id.name : "default";
|
|
585
|
-
const view =
|
|
585
|
+
const view = property(options, "view")?.value;
|
|
586
586
|
if (view?.type !== "Literal" || typeof view.value !== "string")
|
|
587
587
|
fail("Instance view paths must be string literals.");
|
|
588
588
|
if (instances.value.type !== "ObjectExpression")
|
|
@@ -7,7 +7,8 @@ import {
|
|
|
7
7
|
import { createContext, h, render } from "preact";
|
|
8
8
|
import { useContext } from "preact/hooks";
|
|
9
9
|
var preactVersion = "10.29.8";
|
|
10
|
-
var
|
|
10
|
+
var defineView = (options) => {
|
|
11
|
+
const path = options.view;
|
|
11
12
|
const Context2 = createContext(
|
|
12
13
|
null
|
|
13
14
|
);
|
|
@@ -33,6 +34,7 @@ var createView = (path, options) => {
|
|
|
33
34
|
return {
|
|
34
35
|
component: View,
|
|
35
36
|
path,
|
|
37
|
+
slot: options.slot,
|
|
36
38
|
...instances?.resolver ? { instances: { resolver: instances.resolver } } : {},
|
|
37
39
|
useContext: () => {
|
|
38
40
|
const context = useContext(Context2);
|
|
@@ -51,14 +53,25 @@ var createView = (path, options) => {
|
|
|
51
53
|
}
|
|
52
54
|
};
|
|
53
55
|
};
|
|
54
|
-
var defineClient = (client) =>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
var defineClient = (client) => {
|
|
57
|
+
for (const [slot, views] of Object.entries(client.slots)) {
|
|
58
|
+
for (const [path, view] of Object.entries(views ?? {})) {
|
|
59
|
+
if (view !== false && view.slot !== slot)
|
|
60
|
+
throw new Error(`View "${path}" was created for slot "${view.slot}", not "${slot}".`);
|
|
61
|
+
}
|
|
60
62
|
}
|
|
61
|
-
|
|
63
|
+
return {
|
|
64
|
+
...client,
|
|
65
|
+
$meta: { preactVersion },
|
|
66
|
+
$runtime: {
|
|
67
|
+
h,
|
|
68
|
+
render: (vnode, parent) => render(
|
|
69
|
+
vnode && client.component ? h(client.component, { children: vnode }) : vnode,
|
|
70
|
+
parent
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
};
|
|
62
75
|
var componentTagPrefix = "tailorkit-";
|
|
63
76
|
var toComponentTagName = (name) => `${componentTagPrefix}${name.replaceAll(/([a-z0-9])([A-Z])/gu, "$1-$2").replaceAll(/[\s_]+/gu, "-").toLowerCase()}`;
|
|
64
77
|
var toCallbackEventName = (name) => `tailorkitcallback${name.replaceAll(/[^A-Za-z0-9_$]/gu, "").toLowerCase()}`;
|
|
@@ -618,7 +631,7 @@ function useAction(ref, options = {}) {
|
|
|
618
631
|
}
|
|
619
632
|
|
|
620
633
|
export {
|
|
621
|
-
|
|
634
|
+
defineView,
|
|
622
635
|
defineClient,
|
|
623
636
|
createRemoteComponent,
|
|
624
637
|
createSessionProvider,
|
package/dist/client.js
CHANGED
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
createClient,
|
|
5
5
|
createRemoteComponent,
|
|
6
6
|
createSessionProvider,
|
|
7
|
-
createView,
|
|
8
7
|
defineClient,
|
|
8
|
+
defineView,
|
|
9
9
|
reference,
|
|
10
10
|
useAction,
|
|
11
11
|
useMutation,
|
|
12
12
|
useQuery
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-RHCGWGSG.js";
|
|
14
14
|
import {
|
|
15
15
|
AppError,
|
|
16
16
|
appError
|
|
@@ -23,8 +23,8 @@ export {
|
|
|
23
23
|
createClient,
|
|
24
24
|
createRemoteComponent,
|
|
25
25
|
createSessionProvider,
|
|
26
|
-
createView,
|
|
27
26
|
defineClient,
|
|
27
|
+
defineView,
|
|
28
28
|
reference,
|
|
29
29
|
useAction,
|
|
30
30
|
useMutation,
|
package/dist/index.js
CHANGED
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
createClient,
|
|
5
5
|
createRemoteComponent,
|
|
6
6
|
createSessionProvider,
|
|
7
|
-
createView,
|
|
8
7
|
defineClient,
|
|
8
|
+
defineView,
|
|
9
9
|
reference,
|
|
10
10
|
useAction,
|
|
11
11
|
useMutation,
|
|
12
12
|
useQuery
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-RHCGWGSG.js";
|
|
14
14
|
import {
|
|
15
15
|
action,
|
|
16
16
|
and,
|
|
@@ -55,9 +55,9 @@ export {
|
|
|
55
55
|
createClient,
|
|
56
56
|
createRemoteComponent,
|
|
57
57
|
createSessionProvider,
|
|
58
|
-
createView,
|
|
59
58
|
defineClient,
|
|
60
59
|
defineServer,
|
|
60
|
+
defineView,
|
|
61
61
|
desc,
|
|
62
62
|
eq,
|
|
63
63
|
gt,
|
package/dist/views.d.ts
CHANGED
|
@@ -49,9 +49,10 @@ export type ViewRuntimeProps<TPath extends AppViewPath, TData = unknown> = {
|
|
|
49
49
|
status: "error";
|
|
50
50
|
instance?: never;
|
|
51
51
|
};
|
|
52
|
-
export interface ViewDefinition<TPath extends AppViewPath = AppViewPath, TData = unknown> {
|
|
52
|
+
export interface ViewDefinition<TPath extends AppViewPath = AppViewPath, TData = unknown, TSlot extends SlotName = SlotName> {
|
|
53
53
|
component: View<ViewRuntimeProps<TPath>>;
|
|
54
54
|
path: TPath;
|
|
55
|
+
slot: TSlot;
|
|
55
56
|
useContext: () => ViewContext<TPath>;
|
|
56
57
|
/** The selected instance, with data inferred from instances.dataSchema. */
|
|
57
58
|
useInstance: () => ViewInstance<TData>;
|
|
@@ -60,12 +61,6 @@ export interface ViewDefinition<TPath extends AppViewPath = AppViewPath, TData =
|
|
|
60
61
|
resolver: string;
|
|
61
62
|
};
|
|
62
63
|
}
|
|
63
|
-
type RegisteredViews = {
|
|
64
|
-
[TPath in AppViewPath]: ViewDefinition<TPath>;
|
|
65
|
-
};
|
|
66
|
-
type ViewDefinitions = Partial<{
|
|
67
|
-
[P in AppViewPath]: RegisteredViews[P] | false;
|
|
68
|
-
}>;
|
|
69
64
|
type InvalidViewPath<TViews> = Exclude<keyof TViews & string, AppViewPath>;
|
|
70
65
|
type RequireViewPaths<TViews> = InvalidViewPath<TViews> extends never ? unknown : {
|
|
71
66
|
readonly __tailorkit_error__: `View paths must be declared by the host. Invalid view: ${InvalidViewPath<TViews>}`;
|
|
@@ -74,11 +69,24 @@ type ViewKeyPathMismatch<TViews> = {
|
|
|
74
69
|
[TPath in keyof TViews & string]: TViews[TPath] extends false ? never : TViews[TPath] extends ViewDefinition<infer TViewPath> ? TViewPath extends TPath ? never : TPath : TPath;
|
|
75
70
|
}[keyof TViews & string];
|
|
76
71
|
type RequireMatchingViewKeys<TViews> = ViewKeyPathMismatch<TViews> extends never ? unknown : {
|
|
77
|
-
readonly __tailorkit_error__: `View key must match
|
|
72
|
+
readonly __tailorkit_error__: `View key must match defineView path. Invalid view: ${ViewKeyPathMismatch<TViews>}`;
|
|
73
|
+
};
|
|
74
|
+
export type SlotView<TSlot extends SlotName> = TailorKitSlots[TSlot] extends {
|
|
75
|
+
views: infer TViews;
|
|
76
|
+
} ? Extract<TViews, AppViewPath> : never;
|
|
77
|
+
type SlotInstanceDefinition<TSlot extends SlotName> = TailorKitSlots[TSlot] extends {
|
|
78
|
+
multiple: true;
|
|
79
|
+
} ? {
|
|
80
|
+
instances: {
|
|
81
|
+
resolver: string;
|
|
82
|
+
};
|
|
83
|
+
} : {
|
|
84
|
+
instances?: never;
|
|
78
85
|
};
|
|
79
|
-
export type SlotView<TSlot extends SlotName> = Extract<TailorKitSlots[TSlot], AppViewPath>;
|
|
80
86
|
type SlotDefinitions = {
|
|
81
|
-
[V in SlotName]?:
|
|
87
|
+
[V in SlotName]?: Partial<{
|
|
88
|
+
[P in SlotView<V>]: (ViewDefinition<P, unknown, V> & SlotInstanceDefinition<V>) | false;
|
|
89
|
+
}>;
|
|
82
90
|
};
|
|
83
91
|
type RequireSlotViews<V, S> = V extends SlotName ? Exclude<keyof S, SlotView<V>> extends never ? unknown : {
|
|
84
92
|
readonly __tailorkit_error__: "View is not supported by this slot";
|
|
@@ -101,10 +109,22 @@ export type TailorKitClientWithMeta<TViews extends SlotDefinitions = SlotDefinit
|
|
|
101
109
|
$meta: TailorKitClientMeta;
|
|
102
110
|
$runtime: TailorKitClientRuntime;
|
|
103
111
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
112
|
+
type ViewOptions<TPath extends AppViewPath, TSlot extends SlotName, TSchema extends z.ZodType> = {
|
|
113
|
+
[S in TSlot]: {
|
|
114
|
+
slot: S;
|
|
115
|
+
view: TPath;
|
|
116
|
+
component: View<Record<string, never>>;
|
|
117
|
+
} & (TPath extends SlotView<S> ? unknown : {
|
|
118
|
+
readonly __tailorkit_error__: "View is not supported by this slot";
|
|
119
|
+
}) & (TailorKitSlots[S] extends {
|
|
120
|
+
multiple: true;
|
|
121
|
+
} ? {
|
|
122
|
+
instances: ViewInstances<TPath, TSchema>;
|
|
123
|
+
} : {
|
|
124
|
+
instances?: never;
|
|
125
|
+
});
|
|
126
|
+
}[TSlot];
|
|
127
|
+
export declare const defineView: <const TPath extends AppViewPath, const TSlot extends SlotName, TSchema extends z.ZodType>(options: ViewOptions<TPath, TSlot, TSchema>) => ViewDefinition<TPath, z.output<TSchema>, TSlot> & SlotInstanceDefinition<TSlot>;
|
|
108
128
|
export declare const defineClient: <const TSlots extends SlotDefinitions>(client: TailorKitClient<TSlots> & {
|
|
109
129
|
slots: { [V in keyof TSlots]: TSlots[V] & RequireViewPaths<TSlots[V]> & RequireMatchingViewKeys<TSlots[V]> & RequireSlotViews<V, TSlots[V]>; };
|
|
110
130
|
} & (Exclude<keyof TSlots, SlotName> extends never ? unknown : {
|