@tailorkit/react 0.1.0-beta.13 → 0.1.0-beta.14
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/dist/hooks/use-view.d.ts +1 -1
- package/dist/index.js +270 -17
- package/dist/preview-manager.d.ts +11 -0
- package/dist/remote-view.d.ts +2 -1
- package/dist/store.d.ts +7 -1
- package/dist/tailor-kit.d.ts +5 -9
- package/package.json +4 -3
package/dist/hooks/use-view.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { StandardJSONSchemaV1 } from "@standard-schema/spec";
|
|
|
2
2
|
import type { ViewDefinition } from "@tailorkit/core/schema";
|
|
3
3
|
import type { RegisteredViews } from "../tailor-kit";
|
|
4
4
|
export type ViewName<TViews extends Record<string, ViewDefinition>> = keyof TViews & string;
|
|
5
|
-
export type ViewContext<TView> = TView extends
|
|
5
|
+
export type ViewContext<TView> = TView extends StandardJSONSchemaV1 ? StandardJSONSchemaV1.InferOutput<TView> : Record<string, never>;
|
|
6
6
|
interface ReadyViewOptions<TViews extends Record<string, ViewDefinition>, TView extends ViewName<TViews>> {
|
|
7
7
|
context: ViewContext<TViews[TView]>;
|
|
8
8
|
view: TView;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/components/app-view.tsx
|
|
2
|
-
import { useEffect as useEffect2, useId as useId2, useMemo as useMemo3, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
2
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useId as useId2, useMemo as useMemo3, useRef as useRef3, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
3
3
|
import { isViewAncestor as isViewAncestor2 } from "@tailorkit/core/views";
|
|
4
4
|
|
|
5
5
|
// src/view-registry.ts
|
|
@@ -63,8 +63,234 @@ function createViewRegistry() {
|
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
// src/preview-manager.ts
|
|
67
|
+
import {
|
|
68
|
+
createPreviewWebSocketClient,
|
|
69
|
+
previewMetadataSchema
|
|
70
|
+
} from "@tailorkit/client-platform/preview";
|
|
71
|
+
var empty = { revision: 0, source: null };
|
|
72
|
+
function viewerTokenExpiresAt(metadata) {
|
|
73
|
+
const expiresAt = Number(metadata.token.split(".", 1)[0]);
|
|
74
|
+
return Number.isSafeInteger(expiresAt) ? expiresAt : 0;
|
|
75
|
+
}
|
|
76
|
+
function bytesFromBase64(value) {
|
|
77
|
+
const raw = atob(value);
|
|
78
|
+
const bytes = new Uint8Array(raw.length);
|
|
79
|
+
for (let index = 0; index < raw.length; index++) {
|
|
80
|
+
bytes[index] = raw.codePointAt(index) ?? 0;
|
|
81
|
+
}
|
|
82
|
+
return bytes;
|
|
83
|
+
}
|
|
84
|
+
async function verify(candidate) {
|
|
85
|
+
let source = null;
|
|
86
|
+
for (const [fileIndex, file] of candidate.manifest.files.entries()) {
|
|
87
|
+
const parts = candidate.files[fileIndex];
|
|
88
|
+
if (!parts || parts.length !== file.chunks || parts.some((part) => part === null)) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const bytes = new Uint8Array(file.size);
|
|
92
|
+
let offset = 0;
|
|
93
|
+
for (const part of parts) {
|
|
94
|
+
if (!part) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
bytes.set(part, offset);
|
|
98
|
+
offset += part.length;
|
|
99
|
+
}
|
|
100
|
+
if (offset !== file.size) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const digest = [...new Uint8Array(await crypto.subtle.digest("SHA-256", bytes))].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
104
|
+
if (digest !== file.sha256) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
if (file.path === "client.js") {
|
|
108
|
+
source = new TextDecoder().decode(bytes);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return source;
|
|
112
|
+
}
|
|
113
|
+
function createPreviewManager(baseUrl, onEnded) {
|
|
114
|
+
const entries = /* @__PURE__ */ new Map();
|
|
115
|
+
const notify = (entry) => {
|
|
116
|
+
for (const listener of entry.listeners) {
|
|
117
|
+
listener();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const close = (entry) => {
|
|
121
|
+
if (entry.reconnect) {
|
|
122
|
+
clearTimeout(entry.reconnect);
|
|
123
|
+
}
|
|
124
|
+
entry.reconnect = null;
|
|
125
|
+
const socket = entry.socket;
|
|
126
|
+
entry.socket = null;
|
|
127
|
+
socket?.close();
|
|
128
|
+
entry.connecting = false;
|
|
129
|
+
entry.candidate = null;
|
|
130
|
+
};
|
|
131
|
+
const end = (entry) => {
|
|
132
|
+
close(entry);
|
|
133
|
+
entry.metadata = null;
|
|
134
|
+
entry.snapshot = empty;
|
|
135
|
+
notify(entry);
|
|
136
|
+
onEnded();
|
|
137
|
+
};
|
|
138
|
+
const handleEvent = async (entry, event) => {
|
|
139
|
+
if (event.type === "ended") {
|
|
140
|
+
end(entry);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (event.revision <= entry.snapshot.revision) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (event.type === "begin") {
|
|
147
|
+
entry.candidate = {
|
|
148
|
+
revision: event.revision,
|
|
149
|
+
manifest: event.manifest,
|
|
150
|
+
files: event.manifest.files.map((file) => Array.from({ length: file.chunks }, () => null))
|
|
151
|
+
};
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const candidate = entry.candidate;
|
|
155
|
+
if (!candidate || candidate.revision !== event.revision) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (event.type === "chunk") {
|
|
159
|
+
const file = candidate.manifest.files[event.fileIndex];
|
|
160
|
+
const slots = candidate.files[event.fileIndex];
|
|
161
|
+
if (!file || !slots || event.chunkIndex < 0 || event.chunkIndex >= slots.length || slots[event.chunkIndex]) {
|
|
162
|
+
entry.candidate = null;
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const bytes = bytesFromBase64(event.base64);
|
|
166
|
+
if (bytes.length !== Math.min(256 * 1024, file.size - event.chunkIndex * 256 * 1024)) {
|
|
167
|
+
entry.candidate = null;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
slots[event.chunkIndex] = bytes;
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (event.type === "complete") {
|
|
174
|
+
const source = await verify(candidate);
|
|
175
|
+
if (source !== null && entry.candidate === candidate && candidate.revision > entry.snapshot.revision) {
|
|
176
|
+
entry.snapshot = { revision: candidate.revision, source };
|
|
177
|
+
notify(entry);
|
|
178
|
+
}
|
|
179
|
+
if (entry.candidate === candidate) {
|
|
180
|
+
entry.candidate = null;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
const connect = async (entry) => {
|
|
185
|
+
if (!entry.listeners.size || !entry.app.preview || entry.socket || entry.connecting) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
entry.connecting = true;
|
|
189
|
+
const appMetadata = entry.app.preview;
|
|
190
|
+
let metadata = entry.metadata && viewerTokenExpiresAt(entry.metadata) > Math.max(Date.now(), viewerTokenExpiresAt(appMetadata)) ? entry.metadata : appMetadata;
|
|
191
|
+
try {
|
|
192
|
+
const refresh = new URL("preview/metadata", baseUrl);
|
|
193
|
+
refresh.searchParams.set("sessionId", metadata.sessionId);
|
|
194
|
+
const response = await fetch(refresh, { credentials: "same-origin" });
|
|
195
|
+
if (response.ok) {
|
|
196
|
+
metadata = previewMetadataSchema.parse(await response.json());
|
|
197
|
+
entry.metadata = metadata;
|
|
198
|
+
} else if (response.status === 404) {
|
|
199
|
+
end(entry);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
} catch {
|
|
203
|
+
}
|
|
204
|
+
if (!entry.listeners.size) {
|
|
205
|
+
entry.connecting = false;
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const socket = new WebSocket(metadata.websocketUrl, metadata.token);
|
|
209
|
+
entry.socket = socket;
|
|
210
|
+
entry.connecting = false;
|
|
211
|
+
socket.addEventListener("open", () => {
|
|
212
|
+
entry.delay = 1e3;
|
|
213
|
+
const client = createPreviewWebSocketClient(socket);
|
|
214
|
+
void (async () => {
|
|
215
|
+
try {
|
|
216
|
+
const stream = await client.subscribe();
|
|
217
|
+
for await (const event of stream) {
|
|
218
|
+
await handleEvent(entry, event);
|
|
219
|
+
}
|
|
220
|
+
} catch {
|
|
221
|
+
} finally {
|
|
222
|
+
socket.close();
|
|
223
|
+
}
|
|
224
|
+
})();
|
|
225
|
+
});
|
|
226
|
+
socket.addEventListener("error", () => socket.close());
|
|
227
|
+
socket.addEventListener("close", () => {
|
|
228
|
+
if (entry.socket !== socket) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
entry.socket = null;
|
|
232
|
+
entry.candidate = null;
|
|
233
|
+
if (entry.listeners.size) {
|
|
234
|
+
entry.reconnect = setTimeout(() => {
|
|
235
|
+
entry.reconnect = null;
|
|
236
|
+
void connect(entry);
|
|
237
|
+
}, entry.delay);
|
|
238
|
+
entry.delay = Math.min(entry.delay * 2, 3e4);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
};
|
|
242
|
+
return {
|
|
243
|
+
getSnapshot: (sessionId) => entries.get(sessionId)?.snapshot ?? empty,
|
|
244
|
+
updateApp: (app) => {
|
|
245
|
+
const sessionId = app.preview?.sessionId;
|
|
246
|
+
const entry = sessionId && entries.get(sessionId);
|
|
247
|
+
if (entry) {
|
|
248
|
+
entry.app = app;
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
subscribe: (app, listener) => {
|
|
252
|
+
const sessionId = app.preview?.sessionId;
|
|
253
|
+
if (!sessionId) {
|
|
254
|
+
return () => {
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
let entry = entries.get(sessionId);
|
|
258
|
+
if (!entry) {
|
|
259
|
+
entry = {
|
|
260
|
+
app,
|
|
261
|
+
metadata: null,
|
|
262
|
+
candidate: null,
|
|
263
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
264
|
+
snapshot: empty,
|
|
265
|
+
socket: null,
|
|
266
|
+
connecting: false,
|
|
267
|
+
reconnect: null,
|
|
268
|
+
delay: 1e3
|
|
269
|
+
};
|
|
270
|
+
entries.set(sessionId, entry);
|
|
271
|
+
}
|
|
272
|
+
entry.app = app;
|
|
273
|
+
entry.listeners.add(listener);
|
|
274
|
+
void connect(entry);
|
|
275
|
+
return () => {
|
|
276
|
+
entry?.listeners.delete(listener);
|
|
277
|
+
if (entry && !entry.listeners.size) {
|
|
278
|
+
close(entry);
|
|
279
|
+
entries.delete(sessionId);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
},
|
|
283
|
+
dispose: () => {
|
|
284
|
+
for (const entry of entries.values()) {
|
|
285
|
+
close(entry);
|
|
286
|
+
}
|
|
287
|
+
entries.clear();
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
66
292
|
// src/store.ts
|
|
67
|
-
function createTailorKitStore(baseUrlInput, initialApps
|
|
293
|
+
function createTailorKitStore(baseUrlInput, initialApps) {
|
|
68
294
|
const baseUrl = toBaseUrl(baseUrlInput);
|
|
69
295
|
const listeners = /* @__PURE__ */ new Set();
|
|
70
296
|
let providedApps = initialApps;
|
|
@@ -118,9 +344,6 @@ function createTailorKitStore(baseUrlInput, initialApps, previewSessionId) {
|
|
|
118
344
|
emit();
|
|
119
345
|
const requestId = ++fetchAppsRequestId;
|
|
120
346
|
const appsUrl = new URL("apps", baseUrl);
|
|
121
|
-
if (previewSessionId) {
|
|
122
|
-
appsUrl.searchParams.set("previewSessionId", previewSessionId);
|
|
123
|
-
}
|
|
124
347
|
fetchAppsPromise = fetch(appsUrl).then(async (response) => {
|
|
125
348
|
if (!response.ok) {
|
|
126
349
|
throw new Error(`Unable to fetch TailorKit apps from ${baseUrl.toString()}.`);
|
|
@@ -185,7 +408,12 @@ function createTailorKitStore(baseUrlInput, initialApps, previewSessionId) {
|
|
|
185
408
|
};
|
|
186
409
|
}
|
|
187
410
|
};
|
|
188
|
-
return
|
|
411
|
+
return {
|
|
412
|
+
...store,
|
|
413
|
+
previews: createPreviewManager(baseUrl, () => {
|
|
414
|
+
void store.fetchApps({ force: true });
|
|
415
|
+
})
|
|
416
|
+
};
|
|
189
417
|
}
|
|
190
418
|
function toBaseUrl(value) {
|
|
191
419
|
const url = value instanceof URL ? new URL(value) : new URL(value);
|
|
@@ -562,6 +790,7 @@ var RemoteErrorBoundary = class extends Component {
|
|
|
562
790
|
};
|
|
563
791
|
function RemoteViewHost({
|
|
564
792
|
appUrl,
|
|
793
|
+
sourceText,
|
|
565
794
|
components: components2,
|
|
566
795
|
createIframe,
|
|
567
796
|
props
|
|
@@ -609,6 +838,7 @@ function RemoteViewHost({
|
|
|
609
838
|
useEffect(() => {
|
|
610
839
|
const host = createIframeUiHost(appUrl, {
|
|
611
840
|
createIframe,
|
|
841
|
+
sourceText,
|
|
612
842
|
onError: (error2) => {
|
|
613
843
|
console.error("TailorKit remote app failed", error2);
|
|
614
844
|
setError(error2);
|
|
@@ -634,7 +864,7 @@ function RemoteViewHost({
|
|
|
634
864
|
hostRef.current = null;
|
|
635
865
|
host.destroy();
|
|
636
866
|
};
|
|
637
|
-
}, [appUrl, createIframe, store]);
|
|
867
|
+
}, [appUrl, createIframe, sourceText, store]);
|
|
638
868
|
if (status === "error" && error) {
|
|
639
869
|
return createElement("div", null, formatError(error));
|
|
640
870
|
}
|
|
@@ -734,6 +964,29 @@ var AppView = ({
|
|
|
734
964
|
return currentView === null ? void 0 : { slot, ...currentView };
|
|
735
965
|
}, [context, currentView, view, status, slot]);
|
|
736
966
|
const meta = useSyncExternalStore2(store.subscribe, store.getMetaSnapshot, store.getMetaSnapshot);
|
|
967
|
+
const previewSessionId = app.preview?.sessionId ?? "";
|
|
968
|
+
const appRef = useRef3(app);
|
|
969
|
+
appRef.current = app;
|
|
970
|
+
const subscribePreview = useCallback2(
|
|
971
|
+
(listener) => {
|
|
972
|
+
const currentApp = appRef.current;
|
|
973
|
+
return currentApp.preview?.sessionId === previewSessionId ? store.previews.subscribe(currentApp, listener) : () => {
|
|
974
|
+
};
|
|
975
|
+
},
|
|
976
|
+
[store, previewSessionId]
|
|
977
|
+
);
|
|
978
|
+
const getPreviewSnapshot = useCallback2(
|
|
979
|
+
() => store.previews.getSnapshot(previewSessionId),
|
|
980
|
+
[store, previewSessionId]
|
|
981
|
+
);
|
|
982
|
+
const previewSnapshot = useSyncExternalStore2(
|
|
983
|
+
subscribePreview,
|
|
984
|
+
getPreviewSnapshot,
|
|
985
|
+
getPreviewSnapshot
|
|
986
|
+
);
|
|
987
|
+
useEffect2(() => {
|
|
988
|
+
store.previews.updateApp(app);
|
|
989
|
+
}, [store, app]);
|
|
737
990
|
const runtimeProps = useMemo3(
|
|
738
991
|
() => props === void 0 ? void 0 : {
|
|
739
992
|
...props,
|
|
@@ -750,7 +1003,7 @@ var AppView = ({
|
|
|
750
1003
|
useEffect2(() => {
|
|
751
1004
|
void store.fetchMeta();
|
|
752
1005
|
}, [store]);
|
|
753
|
-
if (props === void 0 || appUrl === null || meta.schema === null) {
|
|
1006
|
+
if (props === void 0 || appUrl === null && previewSnapshot.source === null || meta.schema === null) {
|
|
754
1007
|
return fallback;
|
|
755
1008
|
}
|
|
756
1009
|
const viewId = `tailorkit-view-${reactId.replaceAll(":", "")}`;
|
|
@@ -759,11 +1012,13 @@ var AppView = ({
|
|
|
759
1012
|
/* @__PURE__ */ jsx3(
|
|
760
1013
|
RemoteViewHost,
|
|
761
1014
|
{
|
|
762
|
-
appUrl: appUrl.toString(),
|
|
1015
|
+
appUrl: (appUrl ?? new URL(`preview/${previewSessionId}/client.js`, store.baseUrl)).toString(),
|
|
1016
|
+
sourceText: previewSnapshot.source ?? void 0,
|
|
763
1017
|
components: wrappedComponents,
|
|
764
1018
|
createIframe,
|
|
765
1019
|
props: runtimeProps
|
|
766
|
-
}
|
|
1020
|
+
},
|
|
1021
|
+
previewSnapshot.revision || appUrl?.toString()
|
|
767
1022
|
)
|
|
768
1023
|
] }) });
|
|
769
1024
|
};
|
|
@@ -810,7 +1065,6 @@ function createReactTailorKitClient(options) {
|
|
|
810
1065
|
return {
|
|
811
1066
|
baseUrl: options.baseUrl,
|
|
812
1067
|
components: wrappedComponents,
|
|
813
|
-
previewSessionId: options.previewSessionId,
|
|
814
1068
|
theme
|
|
815
1069
|
};
|
|
816
1070
|
}
|
|
@@ -895,17 +1149,16 @@ function isEventHandler(key) {
|
|
|
895
1149
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
896
1150
|
function Root({ apps: appsProp, children, render, client, ...props }) {
|
|
897
1151
|
const baseUrl = toBaseUrl(client.baseUrl).toString();
|
|
898
|
-
const [previousStore, setStore] = useState2(
|
|
899
|
-
() => createTailorKitStore(baseUrl, appsProp, client.previewSessionId)
|
|
900
|
-
);
|
|
1152
|
+
const [previousStore, setStore] = useState2(() => createTailorKitStore(baseUrl, appsProp));
|
|
901
1153
|
let store = previousStore;
|
|
902
1154
|
if (previousStore.baseUrl.toString() !== baseUrl) {
|
|
903
|
-
store = createTailorKitStore(baseUrl, appsProp
|
|
1155
|
+
store = createTailorKitStore(baseUrl, appsProp);
|
|
904
1156
|
setStore(store);
|
|
905
1157
|
}
|
|
906
1158
|
useEffect3(() => {
|
|
907
1159
|
store.setProvidedApps(appsProp);
|
|
908
1160
|
}, [store, appsProp]);
|
|
1161
|
+
useEffect3(() => () => store.previews.dispose(), [store]);
|
|
909
1162
|
const context = useMemo5(
|
|
910
1163
|
() => ({
|
|
911
1164
|
store,
|
|
@@ -922,7 +1175,7 @@ function Root({ apps: appsProp, children, render, client, ...props }) {
|
|
|
922
1175
|
}
|
|
923
1176
|
|
|
924
1177
|
// src/hooks/use-apps.ts
|
|
925
|
-
import { useCallback as
|
|
1178
|
+
import { useCallback as useCallback3, useEffect as useEffect4, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
926
1179
|
function useApps() {
|
|
927
1180
|
return useAppsStore(useTailorRootContext("useApps").store);
|
|
928
1181
|
}
|
|
@@ -935,7 +1188,7 @@ function useAppsStore(store) {
|
|
|
935
1188
|
useEffect4(() => {
|
|
936
1189
|
void store.fetchApps();
|
|
937
1190
|
}, [store]);
|
|
938
|
-
const refetch =
|
|
1191
|
+
const refetch = useCallback3(() => store.fetchApps({ force: true }), [store]);
|
|
939
1192
|
return toUseAppsResult(snapshot, refetch);
|
|
940
1193
|
}
|
|
941
1194
|
function toUseAppsResult(snapshot, refetch) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TailorKitApp } from "./tailor-kit";
|
|
2
|
+
export interface PreviewSnapshot {
|
|
3
|
+
revision: number;
|
|
4
|
+
source: string | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function createPreviewManager(baseUrl: URL, onEnded: () => void): {
|
|
7
|
+
getSnapshot: (sessionId: string) => PreviewSnapshot;
|
|
8
|
+
updateApp: (app: TailorKitApp) => void;
|
|
9
|
+
subscribe: (app: TailorKitApp, listener: () => void) => (() => void);
|
|
10
|
+
dispose: () => void;
|
|
11
|
+
};
|
package/dist/remote-view.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
interface RemoteViewHostProps {
|
|
3
3
|
appUrl: string | URL;
|
|
4
|
+
sourceText?: string;
|
|
4
5
|
components: Record<string, unknown>;
|
|
5
6
|
createIframe?: () => HTMLIFrameElement;
|
|
6
7
|
props?: Record<string, unknown>;
|
|
7
8
|
}
|
|
8
|
-
export declare function RemoteViewHost({ appUrl, components, createIframe, props, }: RemoteViewHostProps): ReactNode;
|
|
9
|
+
export declare function RemoteViewHost({ appUrl, sourceText, components, createIframe, props, }: RemoteViewHostProps): ReactNode;
|
|
9
10
|
interface RemoteViewProps {
|
|
10
11
|
nodeId: string;
|
|
11
12
|
}
|
package/dist/store.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ interface TailorKitMetaSnapshot {
|
|
|
12
12
|
status: "error" | "idle" | "loading" | "ready";
|
|
13
13
|
}
|
|
14
14
|
export type TailorKitStore = ReturnType<typeof createTailorKitStore>;
|
|
15
|
-
export declare function createTailorKitStore(baseUrlInput: string | URL, initialApps?: TailorKitApp[]
|
|
15
|
+
export declare function createTailorKitStore(baseUrlInput: string | URL, initialApps?: TailorKitApp[]): {
|
|
16
16
|
baseUrl: URL;
|
|
17
17
|
views: {
|
|
18
18
|
getSnapshot: () => import("@tailorkit/core/views").ActiveView | null;
|
|
@@ -28,6 +28,12 @@ export declare function createTailorKitStore(baseUrlInput: string | URL, initial
|
|
|
28
28
|
getAppsSnapshot: () => TailorKitAppsSnapshot;
|
|
29
29
|
getMetaSnapshot: () => TailorKitMetaSnapshot;
|
|
30
30
|
subscribe: (listener: () => void) => (() => void);
|
|
31
|
+
previews: {
|
|
32
|
+
getSnapshot: (sessionId: string) => import("./preview-manager").PreviewSnapshot;
|
|
33
|
+
updateApp: (app: TailorKitApp) => void;
|
|
34
|
+
subscribe: (app: TailorKitApp, listener: () => void) => (() => void);
|
|
35
|
+
dispose: () => void;
|
|
36
|
+
};
|
|
31
37
|
};
|
|
32
38
|
export declare function toBaseUrl(value: string | URL): URL;
|
|
33
39
|
export {};
|
package/dist/tailor-kit.d.ts
CHANGED
|
@@ -30,7 +30,9 @@ export interface TailorKitApp {
|
|
|
30
30
|
name?: string;
|
|
31
31
|
preview?: {
|
|
32
32
|
sessionId: string;
|
|
33
|
-
|
|
33
|
+
expiresAt: string;
|
|
34
|
+
websocketUrl: string;
|
|
35
|
+
token: string;
|
|
34
36
|
};
|
|
35
37
|
}
|
|
36
38
|
interface AppViewBaseProps {
|
|
@@ -70,11 +72,6 @@ export interface TailorKitInstance<TViews extends Record<string, ViewDefinition>
|
|
|
70
72
|
readonly $slots?: TSlots;
|
|
71
73
|
readonly $views?: TViews;
|
|
72
74
|
readonly baseUrl: string | URL;
|
|
73
|
-
/**
|
|
74
|
-
* A host-selected, scope-authorized local-development preview session.
|
|
75
|
-
* The host handler resolves this server-side before returning app URLs.
|
|
76
|
-
*/
|
|
77
|
-
readonly previewSessionId?: string;
|
|
78
75
|
readonly components: Record<string, unknown>;
|
|
79
76
|
readonly theme: TailorKitTheme;
|
|
80
77
|
}
|
|
@@ -87,7 +84,7 @@ interface TailorKitServerShape {
|
|
|
87
84
|
$internal: {
|
|
88
85
|
schema: {
|
|
89
86
|
components: Record<string, unknown>;
|
|
90
|
-
|
|
87
|
+
contexts: Record<string, unknown>;
|
|
91
88
|
};
|
|
92
89
|
};
|
|
93
90
|
}
|
|
@@ -95,13 +92,12 @@ type ServerComponentMap<TTailor extends TailorKitServerShape> = TTailor["$intern
|
|
|
95
92
|
type ServerComponents<TTailor extends TailorKitServerShape> = {
|
|
96
93
|
[TName in keyof ServerComponentMap<TTailor>]: ServerComponentMap<TTailor>[TName] extends AnyComponentDefinition ? ServerComponentMap<TTailor>[TName] : never;
|
|
97
94
|
};
|
|
98
|
-
type ServerViewMap<TTailor extends TailorKitServerShape> = TTailor["$internal"]["schema"]["
|
|
95
|
+
type ServerViewMap<TTailor extends TailorKitServerShape> = TTailor["$internal"]["schema"]["contexts"];
|
|
99
96
|
type ServerViews<TTailor extends TailorKitServerShape> = {
|
|
100
97
|
[TName in keyof ServerViewMap<TTailor>]: ServerViewMap<TTailor>[TName] extends ViewDefinition ? ServerViewMap<TTailor>[TName] : never;
|
|
101
98
|
};
|
|
102
99
|
export declare function createTailorKitClient<TTailor extends TailorKitServerShape>(options: {
|
|
103
100
|
baseUrl: string | URL;
|
|
104
|
-
previewSessionId?: string;
|
|
105
101
|
components?: CompleteComponentRenderers<ServerComponents<TTailor>>;
|
|
106
102
|
theme?: TailorKitTheme;
|
|
107
103
|
}): TailorKitInstance<ServerViews<TTailor>, TTailor extends {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailorkit/react",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.14",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,8 +23,9 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@floating-ui/react-dom": "^2.1.9",
|
|
25
25
|
"@standard-schema/spec": "^1.1.0",
|
|
26
|
-
"@tailorkit/
|
|
27
|
-
"@tailorkit/
|
|
26
|
+
"@tailorkit/client-platform": "0.1.0-beta.14",
|
|
27
|
+
"@tailorkit/core": "0.1.0-beta.14",
|
|
28
|
+
"@tailorkit/sandbox": "0.1.0-beta.14"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"@tailorkit/config": "0.0.0",
|