syncorejs 0.2.1 → 0.2.2
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 +2 -1
- package/dist/_vendor/cli/app.d.mts.map +1 -1
- package/dist/_vendor/cli/app.mjs +323 -42
- package/dist/_vendor/cli/app.mjs.map +1 -1
- package/dist/_vendor/cli/context.mjs +27 -9
- package/dist/_vendor/cli/context.mjs.map +1 -1
- package/dist/_vendor/cli/doctor.mjs +513 -46
- package/dist/_vendor/cli/doctor.mjs.map +1 -1
- package/dist/_vendor/cli/messages.mjs +5 -4
- package/dist/_vendor/cli/messages.mjs.map +1 -1
- package/dist/_vendor/cli/project.mjs +110 -12
- package/dist/_vendor/cli/project.mjs.map +1 -1
- package/dist/_vendor/cli/render.mjs +57 -9
- package/dist/_vendor/cli/render.mjs.map +1 -1
- package/dist/_vendor/cli/targets.mjs +4 -3
- package/dist/_vendor/cli/targets.mjs.map +1 -1
- package/dist/_vendor/core/cli.d.mts +13 -3
- package/dist/_vendor/core/cli.d.mts.map +1 -1
- package/dist/_vendor/core/cli.mjs +242 -91
- package/dist/_vendor/core/cli.mjs.map +1 -1
- package/dist/_vendor/core/devtools-auth.mjs +60 -0
- package/dist/_vendor/core/devtools-auth.mjs.map +1 -0
- package/dist/_vendor/core/index.d.mts +5 -3
- package/dist/_vendor/core/index.mjs +22 -2
- package/dist/_vendor/core/index.mjs.map +1 -1
- package/dist/_vendor/core/runtime/components.d.mts +111 -0
- package/dist/_vendor/core/runtime/components.d.mts.map +1 -0
- package/dist/_vendor/core/runtime/components.mjs +186 -0
- package/dist/_vendor/core/runtime/components.mjs.map +1 -0
- package/dist/_vendor/core/runtime/devtools.d.mts +4 -4
- package/dist/_vendor/core/runtime/devtools.d.mts.map +1 -1
- package/dist/_vendor/core/runtime/devtools.mjs +52 -41
- package/dist/_vendor/core/runtime/devtools.mjs.map +1 -1
- package/dist/_vendor/core/runtime/functions.d.mts +10 -10
- package/dist/_vendor/core/runtime/functions.d.mts.map +1 -1
- package/dist/_vendor/core/runtime/functions.mjs +2 -2
- package/dist/_vendor/core/runtime/functions.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs +77 -0
- package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs.map +1 -0
- package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs +617 -0
- package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs.map +1 -0
- package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs +186 -0
- package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs.map +1 -0
- package/dist/_vendor/core/runtime/internal/engines/schedulerEngine.mjs +220 -0
- package/dist/_vendor/core/runtime/internal/engines/schedulerEngine.mjs.map +1 -0
- package/dist/_vendor/core/runtime/internal/engines/schemaEngine.mjs +203 -0
- package/dist/_vendor/core/runtime/internal/engines/schemaEngine.mjs.map +1 -0
- package/dist/_vendor/core/runtime/internal/engines/shared.mjs +177 -0
- package/dist/_vendor/core/runtime/internal/engines/shared.mjs.map +1 -0
- package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs +144 -0
- package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs.map +1 -0
- package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs +220 -0
- package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs.map +1 -0
- package/dist/_vendor/core/runtime/internal/runtimeStatus.mjs +32 -0
- package/dist/_vendor/core/runtime/internal/runtimeStatus.mjs.map +1 -0
- package/dist/_vendor/core/runtime/internal/systemMeta.mjs +61 -0
- package/dist/_vendor/core/runtime/internal/systemMeta.mjs.map +1 -0
- package/dist/_vendor/core/runtime/internal/transactionCoordinator.mjs +37 -0
- package/dist/_vendor/core/runtime/internal/transactionCoordinator.mjs.map +1 -0
- package/dist/_vendor/core/runtime/runtime.d.mts +159 -205
- package/dist/_vendor/core/runtime/runtime.d.mts.map +1 -1
- package/dist/_vendor/core/runtime/runtime.mjs +16 -1371
- package/dist/_vendor/core/runtime/runtime.mjs.map +1 -1
- package/dist/_vendor/core/transport.d.mts +111 -0
- package/dist/_vendor/core/transport.d.mts.map +1 -0
- package/dist/_vendor/core/transport.mjs +419 -0
- package/dist/_vendor/core/transport.mjs.map +1 -0
- package/dist/_vendor/devtools-protocol/index.d.ts +39 -1
- package/dist/_vendor/devtools-protocol/index.d.ts.map +1 -1
- package/dist/_vendor/devtools-protocol/index.js +25 -9
- package/dist/_vendor/devtools-protocol/index.js.map +1 -1
- package/dist/_vendor/next/index.d.ts +1 -1
- package/dist/_vendor/next/index.d.ts.map +1 -1
- package/dist/_vendor/next/index.js +31 -13
- package/dist/_vendor/next/index.js.map +1 -1
- package/dist/_vendor/platform-expo/index.d.ts +12 -12
- package/dist/_vendor/platform-expo/index.d.ts.map +1 -1
- package/dist/_vendor/platform-expo/index.js +4 -2
- package/dist/_vendor/platform-expo/index.js.map +1 -1
- package/dist/_vendor/platform-expo/react.d.ts.map +1 -1
- package/dist/_vendor/platform-expo/react.js +11 -10
- package/dist/_vendor/platform-expo/react.js.map +1 -1
- package/dist/_vendor/platform-node/index.d.mts +23 -19
- package/dist/_vendor/platform-node/index.d.mts.map +1 -1
- package/dist/_vendor/platform-node/index.mjs +13 -5
- package/dist/_vendor/platform-node/index.mjs.map +1 -1
- package/dist/_vendor/platform-node/ipc-react.d.mts.map +1 -1
- package/dist/_vendor/platform-node/ipc-react.mjs +15 -2
- package/dist/_vendor/platform-node/ipc-react.mjs.map +1 -1
- package/dist/_vendor/platform-node/ipc.d.mts +11 -35
- package/dist/_vendor/platform-node/ipc.d.mts.map +1 -1
- package/dist/_vendor/platform-node/ipc.mjs +3 -273
- package/dist/_vendor/platform-node/ipc.mjs.map +1 -1
- package/dist/_vendor/platform-web/external-change.d.ts +2 -1
- package/dist/_vendor/platform-web/external-change.d.ts.map +1 -1
- package/dist/_vendor/platform-web/external-change.js +2 -1
- package/dist/_vendor/platform-web/external-change.js.map +1 -1
- package/dist/_vendor/platform-web/index.d.ts +21 -21
- package/dist/_vendor/platform-web/index.d.ts.map +1 -1
- package/dist/_vendor/platform-web/index.js +44 -7
- package/dist/_vendor/platform-web/index.js.map +1 -1
- package/dist/_vendor/platform-web/react.d.ts.map +1 -1
- package/dist/_vendor/platform-web/react.js +29 -13
- package/dist/_vendor/platform-web/react.js.map +1 -1
- package/dist/_vendor/platform-web/worker.d.ts +11 -35
- package/dist/_vendor/platform-web/worker.d.ts.map +1 -1
- package/dist/_vendor/platform-web/worker.js +3 -267
- package/dist/_vendor/platform-web/worker.js.map +1 -1
- package/dist/_vendor/react/index.d.ts +36 -20
- package/dist/_vendor/react/index.d.ts.map +1 -1
- package/dist/_vendor/react/index.js +279 -57
- package/dist/_vendor/react/index.js.map +1 -1
- package/dist/_vendor/schema/definition.d.ts +48 -63
- package/dist/_vendor/schema/definition.d.ts.map +1 -1
- package/dist/_vendor/schema/definition.js +22 -39
- package/dist/_vendor/schema/definition.js.map +1 -1
- package/dist/_vendor/schema/index.d.ts +4 -4
- package/dist/_vendor/schema/index.js +2 -2
- package/dist/_vendor/schema/planner.d.ts +19 -2
- package/dist/_vendor/schema/planner.d.ts.map +1 -1
- package/dist/_vendor/schema/planner.js +79 -3
- package/dist/_vendor/schema/planner.js.map +1 -1
- package/dist/_vendor/schema/validators.d.ts +141 -121
- package/dist/_vendor/schema/validators.d.ts.map +1 -1
- package/dist/_vendor/schema/validators.js +300 -42
- package/dist/_vendor/schema/validators.js.map +1 -1
- package/dist/_vendor/svelte/index.d.ts +47 -19
- package/dist/_vendor/svelte/index.d.ts.map +1 -1
- package/dist/_vendor/svelte/index.js +250 -20
- package/dist/_vendor/svelte/index.js.map +1 -1
- package/dist/components.d.ts +2 -0
- package/dist/components.js +2 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/package.json +8 -3
|
@@ -3,6 +3,7 @@ import { generateId } from "./runtime/id.mjs";
|
|
|
3
3
|
import { SyncoreRuntime } from "./runtime/runtime.mjs";
|
|
4
4
|
import { createDevtoolsCommandHandler, createDevtoolsSubscriptionHost } from "./runtime/devtools.mjs";
|
|
5
5
|
import { src_exports } from "./index.mjs";
|
|
6
|
+
import { generateDevtoolsToken, isAllowedDashboardOrigin, isAuthorizedDashboardRequest, sanitizeDevtoolsToken } from "./devtools-auth.mjs";
|
|
6
7
|
import { appendFile, mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
7
8
|
import { createServer } from "node:http";
|
|
8
9
|
import { connect } from "node:net";
|
|
@@ -12,11 +13,15 @@ import { DatabaseSync } from "node:sqlite";
|
|
|
12
13
|
import { Command } from "commander";
|
|
13
14
|
import { tsImport } from "tsx/esm/api";
|
|
14
15
|
import WebSocket, { WebSocketServer } from "ws";
|
|
15
|
-
import { createPublicRuntimeId, createPublicTargetId } from "../devtools-protocol/index.js";
|
|
16
|
+
import { SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION, SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION, SYNCORE_DEVTOOLS_PROTOCOL_VERSION, createPublicRuntimeId, createPublicTargetId } from "../devtools-protocol/index.js";
|
|
16
17
|
//#region src/cli.ts
|
|
18
|
+
function templateUsesConnectedClients(template) {
|
|
19
|
+
return template === "react-web" || template === "expo" || template === "next";
|
|
20
|
+
}
|
|
17
21
|
const COMBINED_DEV_COMMAND = "concurrently --kill-others-on-fail --names syncore,app --prefix-colors yellow,cyan \"bun run syncorejs:dev\" \"bun run dev:app\"";
|
|
18
22
|
const program = new Command();
|
|
19
23
|
const CORE_PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
24
|
+
const DEVTOOLS_SESSION_FILE = path.join(".syncore", "devtools-session.json");
|
|
20
25
|
const SYNCORE_MIGRATION_SNAPSHOT_FILE_NAME = "_schema_snapshot.json";
|
|
21
26
|
const VALID_SYNCORE_TEMPLATES = [
|
|
22
27
|
"minimal",
|
|
@@ -123,8 +128,10 @@ if (isCliEntryPoint()) await runSyncoreCli();
|
|
|
123
128
|
async function runCodegen(cwd) {
|
|
124
129
|
const functionsDir = path.join(cwd, "syncore", "functions");
|
|
125
130
|
const generatedDir = path.join(cwd, "syncore", "_generated");
|
|
131
|
+
const componentsManifestPath = path.join(cwd, "syncore", "components.ts");
|
|
126
132
|
await mkdir(generatedDir, { recursive: true });
|
|
127
133
|
const functionImportExtension = await resolveFunctionImportExtension(cwd);
|
|
134
|
+
const hasComponentsManifest = await fileExists(componentsManifestPath);
|
|
128
135
|
const files = await listTypeScriptFiles(functionsDir);
|
|
129
136
|
const functionEntries = [];
|
|
130
137
|
for (const file of files) {
|
|
@@ -148,6 +155,8 @@ async function runCodegen(cwd) {
|
|
|
148
155
|
``,
|
|
149
156
|
`import { createFunctionReferenceFor } from "syncorejs";`,
|
|
150
157
|
`import type { FunctionReferenceFor } from "syncorejs";`,
|
|
158
|
+
`export { components } from "./components${functionImportExtension}";`,
|
|
159
|
+
``,
|
|
151
160
|
...renderFunctionTypeImports(functionEntries, functionImportExtension),
|
|
152
161
|
``,
|
|
153
162
|
...renderGeneratedApiInterfaces(functionEntries),
|
|
@@ -174,9 +183,12 @@ async function runCodegen(cwd) {
|
|
|
174
183
|
` */`,
|
|
175
184
|
``,
|
|
176
185
|
`import type { SyncoreFunctionRegistry } from "syncorejs";`,
|
|
177
|
-
|
|
186
|
+
`import { composeProjectFunctionRegistry } from "syncorejs";`,
|
|
187
|
+
...renderGeneratedManifestImportLines(hasComponentsManifest, functionImportExtension),
|
|
178
188
|
...renderFunctionImports(functionEntries, functionImportExtension),
|
|
179
189
|
``,
|
|
190
|
+
...renderGeneratedManifestDeclarationLines(hasComponentsManifest),
|
|
191
|
+
``,
|
|
180
192
|
...renderGeneratedFunctionsInterface(functionEntries),
|
|
181
193
|
``,
|
|
182
194
|
`/**`,
|
|
@@ -184,9 +196,54 @@ async function runCodegen(cwd) {
|
|
|
184
196
|
` *`,
|
|
185
197
|
` * Most application code should import from \`./api\` instead of using this map directly.`,
|
|
186
198
|
` */`,
|
|
187
|
-
`
|
|
199
|
+
`const rootFunctions: SyncoreRootFunctionsRegistry = {`,
|
|
188
200
|
...functionEntries.map((entry) => ` ${JSON.stringify(`${entry.pathParts.join("/")}/${entry.exportName}`)}: ${renderFunctionImportName(entry)},`),
|
|
189
201
|
`} as const;`,
|
|
202
|
+
``,
|
|
203
|
+
`export const functions: SyncoreFunctionRegistry = composeProjectFunctionRegistry(rootFunctions, componentsManifest);`,
|
|
204
|
+
``
|
|
205
|
+
].join("\n");
|
|
206
|
+
const schemaSource = [
|
|
207
|
+
`/**`,
|
|
208
|
+
` * Generated composed Syncore schema including installed components.`,
|
|
209
|
+
` *`,
|
|
210
|
+
` * THIS CODE IS AUTOMATICALLY GENERATED.`,
|
|
211
|
+
` *`,
|
|
212
|
+
` * To regenerate, run \`npx syncorejs dev\` or \`npx syncorejs codegen\`.`,
|
|
213
|
+
` * @module`,
|
|
214
|
+
` */`,
|
|
215
|
+
``,
|
|
216
|
+
`import { composeProjectSchema } from "syncorejs";`,
|
|
217
|
+
`import rootSchema from "../schema${functionImportExtension}";`,
|
|
218
|
+
...renderGeneratedManifestImportLines(hasComponentsManifest, functionImportExtension),
|
|
219
|
+
``,
|
|
220
|
+
...renderGeneratedManifestDeclarationLines(hasComponentsManifest),
|
|
221
|
+
``,
|
|
222
|
+
`const schema = composeProjectSchema(rootSchema, componentsManifest);`,
|
|
223
|
+
``,
|
|
224
|
+
`export default schema;`,
|
|
225
|
+
``
|
|
226
|
+
].join("\n");
|
|
227
|
+
const componentsSource = [
|
|
228
|
+
`/**`,
|
|
229
|
+
` * Generated installed-component helpers for this Syncore app.`,
|
|
230
|
+
` *`,
|
|
231
|
+
` * THIS CODE IS AUTOMATICALLY GENERATED.`,
|
|
232
|
+
` *`,
|
|
233
|
+
` * To regenerate, run \`npx syncorejs dev\` or \`npx syncorejs codegen\`.`,
|
|
234
|
+
` * @module`,
|
|
235
|
+
` */`,
|
|
236
|
+
``,
|
|
237
|
+
`import { createInstalledComponentsApi, resolveComponentsManifest } from "syncorejs";`,
|
|
238
|
+
...renderGeneratedManifestImportLines(hasComponentsManifest, functionImportExtension),
|
|
239
|
+
``,
|
|
240
|
+
...renderGeneratedManifestDeclarationLines(hasComponentsManifest),
|
|
241
|
+
``,
|
|
242
|
+
`export const components = createInstalledComponentsApi(componentsManifest);`,
|
|
243
|
+
``,
|
|
244
|
+
`export const resolvedComponents = resolveComponentsManifest(componentsManifest);`,
|
|
245
|
+
``,
|
|
246
|
+
`export default resolvedComponents;`,
|
|
190
247
|
``
|
|
191
248
|
].join("\n");
|
|
192
249
|
const serverSource = [
|
|
@@ -213,7 +270,7 @@ async function runCodegen(cwd) {
|
|
|
213
270
|
` ValidatorMap`,
|
|
214
271
|
`} from "syncorejs";`,
|
|
215
272
|
``,
|
|
216
|
-
`export { createFunctionReference, createFunctionReferenceFor,
|
|
273
|
+
`export { createFunctionReference, createFunctionReferenceFor, s } from "syncorejs";`,
|
|
217
274
|
``,
|
|
218
275
|
`/**`,
|
|
219
276
|
` * The context object available inside Syncore query handlers in this app.`,
|
|
@@ -240,22 +297,14 @@ async function runCodegen(cwd) {
|
|
|
240
297
|
` * @param config - The query definition, including args and a handler.`,
|
|
241
298
|
` * @returns The wrapped query. Export it from \`syncore/functions\` to add it to the generated API.`,
|
|
242
299
|
` */`,
|
|
243
|
-
`export
|
|
244
|
-
`
|
|
245
|
-
`
|
|
246
|
-
`
|
|
247
|
-
`
|
|
248
|
-
`
|
|
249
|
-
`
|
|
250
|
-
`
|
|
251
|
-
`) {`,
|
|
252
|
-
` return baseQuery(config as never) as SyncoreFunctionDefinition<`,
|
|
253
|
-
` "query",`,
|
|
254
|
-
` QueryCtx,`,
|
|
255
|
-
` InferArgs<TArgsShape>,`,
|
|
256
|
-
` TResult`,
|
|
257
|
-
` >;`,
|
|
258
|
-
`}`,
|
|
300
|
+
`export const query = baseQuery as {`,
|
|
301
|
+
` <TValidator extends Validator<unknown, unknown, string>, TResult>(`,
|
|
302
|
+
` config: FunctionConfig<QueryCtx, Infer<TValidator>, TResult> & { args: TValidator }`,
|
|
303
|
+
` ): SyncoreFunctionDefinition<"query", QueryCtx, Infer<TValidator>, TResult>;`,
|
|
304
|
+
` <TArgsShape extends ValidatorMap, TResult>(`,
|
|
305
|
+
` config: FunctionConfig<QueryCtx, InferArgs<TArgsShape>, TResult> & { args: TArgsShape }`,
|
|
306
|
+
` ): SyncoreFunctionDefinition<"query", QueryCtx, InferArgs<TArgsShape>, TResult>;`,
|
|
307
|
+
`};`,
|
|
259
308
|
``,
|
|
260
309
|
`/**`,
|
|
261
310
|
` * Define a mutation in this Syncore app's public API.`,
|
|
@@ -265,22 +314,14 @@ async function runCodegen(cwd) {
|
|
|
265
314
|
` * @param config - The mutation definition, including args and a handler.`,
|
|
266
315
|
` * @returns The wrapped mutation. Export it from \`syncore/functions\` to add it to the generated API.`,
|
|
267
316
|
` */`,
|
|
268
|
-
`export
|
|
269
|
-
`
|
|
270
|
-
`
|
|
271
|
-
`
|
|
272
|
-
`
|
|
273
|
-
`
|
|
274
|
-
`
|
|
275
|
-
`
|
|
276
|
-
`) {`,
|
|
277
|
-
` return baseMutation(config as never) as SyncoreFunctionDefinition<`,
|
|
278
|
-
` "mutation",`,
|
|
279
|
-
` MutationCtx,`,
|
|
280
|
-
` InferArgs<TArgsShape>,`,
|
|
281
|
-
` TResult`,
|
|
282
|
-
` >;`,
|
|
283
|
-
`}`,
|
|
317
|
+
`export const mutation = baseMutation as {`,
|
|
318
|
+
` <TValidator extends Validator<unknown, unknown, string>, TResult>(`,
|
|
319
|
+
` config: FunctionConfig<MutationCtx, Infer<TValidator>, TResult> & { args: TValidator }`,
|
|
320
|
+
` ): SyncoreFunctionDefinition<"mutation", MutationCtx, Infer<TValidator>, TResult>;`,
|
|
321
|
+
` <TArgsShape extends ValidatorMap, TResult>(`,
|
|
322
|
+
` config: FunctionConfig<MutationCtx, InferArgs<TArgsShape>, TResult> & { args: TArgsShape }`,
|
|
323
|
+
` ): SyncoreFunctionDefinition<"mutation", MutationCtx, InferArgs<TArgsShape>, TResult>;`,
|
|
324
|
+
`};`,
|
|
284
325
|
``,
|
|
285
326
|
`/**`,
|
|
286
327
|
` * Define an action in this Syncore app's public API.`,
|
|
@@ -290,26 +331,20 @@ async function runCodegen(cwd) {
|
|
|
290
331
|
` * @param config - The action definition, including args and a handler.`,
|
|
291
332
|
` * @returns The wrapped action. Export it from \`syncore/functions\` to add it to the generated API.`,
|
|
292
333
|
` */`,
|
|
293
|
-
`export
|
|
294
|
-
`
|
|
295
|
-
`
|
|
296
|
-
`
|
|
297
|
-
`
|
|
298
|
-
`
|
|
299
|
-
`
|
|
300
|
-
`
|
|
301
|
-
`) {`,
|
|
302
|
-
` return baseAction(config as never) as SyncoreFunctionDefinition<`,
|
|
303
|
-
` "action",`,
|
|
304
|
-
` ActionCtx,`,
|
|
305
|
-
` InferArgs<TArgsShape>,`,
|
|
306
|
-
` TResult`,
|
|
307
|
-
` >;`,
|
|
308
|
-
`}`,
|
|
334
|
+
`export const action = baseAction as {`,
|
|
335
|
+
` <TValidator extends Validator<unknown, unknown, string>, TResult>(`,
|
|
336
|
+
` config: FunctionConfig<ActionCtx, Infer<TValidator>, TResult> & { args: TValidator }`,
|
|
337
|
+
` ): SyncoreFunctionDefinition<"action", ActionCtx, Infer<TValidator>, TResult>;`,
|
|
338
|
+
` <TArgsShape extends ValidatorMap, TResult>(`,
|
|
339
|
+
` config: FunctionConfig<ActionCtx, InferArgs<TArgsShape>, TResult> & { args: TArgsShape }`,
|
|
340
|
+
` ): SyncoreFunctionDefinition<"action", ActionCtx, InferArgs<TArgsShape>, TResult>;`,
|
|
341
|
+
`};`,
|
|
309
342
|
``
|
|
310
343
|
].join("\n");
|
|
311
344
|
await writeFile(path.join(generatedDir, "api.ts"), apiSource);
|
|
345
|
+
await writeFile(path.join(generatedDir, "components.ts"), componentsSource);
|
|
312
346
|
await writeFile(path.join(generatedDir, "functions.ts"), functionsSource);
|
|
347
|
+
await writeFile(path.join(generatedDir, "schema.ts"), schemaSource);
|
|
313
348
|
await writeFile(path.join(generatedDir, "server.ts"), serverSource);
|
|
314
349
|
}
|
|
315
350
|
async function scaffoldProject(cwd, options) {
|
|
@@ -345,19 +380,26 @@ function buildTemplateFiles(template) {
|
|
|
345
380
|
},
|
|
346
381
|
{
|
|
347
382
|
path: path.join("syncore", "schema.ts"),
|
|
348
|
-
content: `import { defineSchema, defineTable,
|
|
383
|
+
content: `import { defineSchema, defineTable, s } from "syncorejs";
|
|
349
384
|
|
|
350
385
|
export default defineSchema({
|
|
351
386
|
tasks: defineTable({
|
|
352
|
-
text:
|
|
353
|
-
done:
|
|
387
|
+
text: s.string(),
|
|
388
|
+
done: s.boolean()
|
|
354
389
|
}).index("by_done", ["done"])
|
|
355
390
|
});
|
|
391
|
+
`
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
path: path.join("syncore", "components.ts"),
|
|
395
|
+
content: `import { defineComponents } from "syncorejs";
|
|
396
|
+
|
|
397
|
+
export default defineComponents({});
|
|
356
398
|
`
|
|
357
399
|
},
|
|
358
400
|
{
|
|
359
401
|
path: path.join("syncore", "functions", "tasks.ts"),
|
|
360
|
-
content: `import { mutation, query,
|
|
402
|
+
content: `import { mutation, query, s } from "../_generated/server";
|
|
361
403
|
|
|
362
404
|
export const list = query({
|
|
363
405
|
args: {},
|
|
@@ -366,7 +408,7 @@ export const list = query({
|
|
|
366
408
|
});
|
|
367
409
|
|
|
368
410
|
export const create = mutation({
|
|
369
|
-
args: { text:
|
|
411
|
+
args: { text: s.string() },
|
|
370
412
|
handler: async (ctx, args) =>
|
|
371
413
|
ctx.db.insert("tasks", { text: args.text, done: false })
|
|
372
414
|
});
|
|
@@ -380,13 +422,15 @@ export const create = mutation({
|
|
|
380
422
|
content: `/// <reference lib="webworker" />
|
|
381
423
|
|
|
382
424
|
import { createBrowserWorkerRuntime } from "syncorejs/browser";
|
|
383
|
-
import schema from "../syncore/schema";
|
|
425
|
+
import schema from "../syncore/_generated/schema";
|
|
426
|
+
import { resolvedComponents } from "../syncore/_generated/components";
|
|
384
427
|
import { functions } from "../syncore/_generated/functions";
|
|
385
428
|
|
|
386
429
|
void createBrowserWorkerRuntime({
|
|
387
430
|
endpoint: self,
|
|
388
431
|
schema,
|
|
389
432
|
functions,
|
|
433
|
+
components: resolvedComponents,
|
|
390
434
|
databaseName: "syncore-app",
|
|
391
435
|
persistenceMode: "opfs"
|
|
392
436
|
});
|
|
@@ -410,12 +454,14 @@ export function AppSyncoreProvider({ children }: { children: ReactNode }) {
|
|
|
410
454
|
files.push({
|
|
411
455
|
path: path.join("lib", "syncore.ts"),
|
|
412
456
|
content: `import { createExpoSyncoreBootstrap } from "syncorejs/expo";
|
|
413
|
-
import schema from "../syncore/schema";
|
|
457
|
+
import schema from "../syncore/_generated/schema";
|
|
458
|
+
import { resolvedComponents } from "../syncore/_generated/components";
|
|
414
459
|
import { functions } from "../syncore/_generated/functions";
|
|
415
460
|
|
|
416
461
|
export const syncore = createExpoSyncoreBootstrap({
|
|
417
462
|
schema,
|
|
418
463
|
functions,
|
|
464
|
+
components: resolvedComponents,
|
|
419
465
|
databaseName: "syncore-app.db",
|
|
420
466
|
storageDirectoryName: "syncore-app-storage"
|
|
421
467
|
});
|
|
@@ -428,13 +474,15 @@ export const syncore = createExpoSyncoreBootstrap({
|
|
|
428
474
|
content: `/* eslint-disable */
|
|
429
475
|
|
|
430
476
|
import { createBrowserWorkerRuntime } from "syncorejs/browser";
|
|
431
|
-
import schema from "../syncore/schema";
|
|
477
|
+
import schema from "../syncore/_generated/schema";
|
|
478
|
+
import { resolvedComponents } from "../syncore/_generated/components";
|
|
432
479
|
import { functions } from "../syncore/_generated/functions";
|
|
433
480
|
|
|
434
481
|
void createBrowserWorkerRuntime({
|
|
435
482
|
endpoint: self,
|
|
436
483
|
schema,
|
|
437
484
|
functions,
|
|
485
|
+
components: resolvedComponents,
|
|
438
486
|
databaseName: "syncore-app",
|
|
439
487
|
persistenceDatabaseName: "syncore-app",
|
|
440
488
|
locateFile: () => "/sql-wasm.wasm",
|
|
@@ -469,7 +517,8 @@ export function AppSyncoreProvider({ children }: { children: ReactNode }) {
|
|
|
469
517
|
content: `import path from "node:path";
|
|
470
518
|
import { withNodeSyncoreClient } from "syncorejs/node";
|
|
471
519
|
import { api } from "./syncore/_generated/api.ts";
|
|
472
|
-
import schema from "./syncore/schema.ts";
|
|
520
|
+
import schema from "./syncore/_generated/schema.ts";
|
|
521
|
+
import { resolvedComponents } from "./syncore/_generated/components.ts";
|
|
473
522
|
import { functions } from "./syncore/_generated/functions.ts";
|
|
474
523
|
|
|
475
524
|
await withNodeSyncoreClient(
|
|
@@ -477,7 +526,8 @@ await withNodeSyncoreClient(
|
|
|
477
526
|
databasePath: path.join(process.cwd(), ".syncore", "syncore.db"),
|
|
478
527
|
storageDirectory: path.join(process.cwd(), ".syncore", "storage"),
|
|
479
528
|
schema,
|
|
480
|
-
functions
|
|
529
|
+
functions,
|
|
530
|
+
components: resolvedComponents
|
|
481
531
|
},
|
|
482
532
|
async (client) => {
|
|
483
533
|
await client.mutation(api.tasks.create, { text: "Run locally" });
|
|
@@ -493,7 +543,8 @@ await withNodeSyncoreClient(
|
|
|
493
543
|
content: `import path from "node:path";
|
|
494
544
|
import { app } from "electron";
|
|
495
545
|
import { createNodeSyncoreRuntime } from "syncorejs/node";
|
|
496
|
-
import schema from "../syncore/schema.js";
|
|
546
|
+
import schema from "../syncore/_generated/schema.js";
|
|
547
|
+
import { resolvedComponents } from "../syncore/_generated/components.js";
|
|
497
548
|
import { functions } from "../syncore/_generated/functions.js";
|
|
498
549
|
|
|
499
550
|
export function createAppSyncoreRuntime() {
|
|
@@ -503,6 +554,7 @@ export function createAppSyncoreRuntime() {
|
|
|
503
554
|
storageDirectory: path.join(userDataDirectory, "storage"),
|
|
504
555
|
schema,
|
|
505
556
|
functions,
|
|
557
|
+
components: resolvedComponents,
|
|
506
558
|
platform: "electron-main"
|
|
507
559
|
});
|
|
508
560
|
}
|
|
@@ -768,12 +820,19 @@ function renderGeneratedFunctionsInterface(functionEntries) {
|
|
|
768
820
|
`/**`,
|
|
769
821
|
` * Type-safe runtime definitions for every function exported from \`syncore/functions\`.`,
|
|
770
822
|
` */`,
|
|
771
|
-
`export interface
|
|
823
|
+
`export interface SyncoreRootFunctionsRegistry extends SyncoreFunctionRegistry {`
|
|
772
824
|
];
|
|
773
825
|
for (const entry of functionEntries.slice().sort((left, right) => `${left.pathParts.join("/")}/${left.exportName}`.localeCompare(`${right.pathParts.join("/")}/${right.exportName}`))) lines.push(` /**`, ` * Runtime definition for the public Syncore ${entry.kind} \`${entry.pathParts.join("/")}/${entry.exportName}\`.`, ` */`, ` readonly ${JSON.stringify(`${entry.pathParts.join("/")}/${entry.exportName}`)}: typeof ${renderFunctionImportName(entry)};`);
|
|
774
826
|
lines.push(`}`);
|
|
775
827
|
return [lines.join("\n")];
|
|
776
828
|
}
|
|
829
|
+
function renderGeneratedManifestImportLines(hasComponentsManifest, extension) {
|
|
830
|
+
if (!hasComponentsManifest) return [];
|
|
831
|
+
return [`import componentsManifest from "../components${extension}";`];
|
|
832
|
+
}
|
|
833
|
+
function renderGeneratedManifestDeclarationLines(hasComponentsManifest) {
|
|
834
|
+
return hasComponentsManifest ? [] : [`const componentsManifest = {} as const;`];
|
|
835
|
+
}
|
|
777
836
|
function renderApiInterfaceName(node) {
|
|
778
837
|
if (node.pathParts.length === 0) return "SyncoreApi";
|
|
779
838
|
return `SyncoreApi__${node.pathParts.map(toTypeNamePart).join("__")}`;
|
|
@@ -831,11 +890,25 @@ function requireProjectTargetConfig(config) {
|
|
|
831
890
|
if (!projectTarget) throw new Error("This Syncore project does not define a projectTarget. Use a connected client target instead.");
|
|
832
891
|
return projectTarget;
|
|
833
892
|
}
|
|
834
|
-
async function
|
|
893
|
+
async function loadProjectRootSchema(cwd) {
|
|
835
894
|
const schema = await loadDefaultExport(path.join(cwd, "syncore", "schema.ts"));
|
|
836
895
|
if (!schema || typeof schema !== "object" || typeof schema.tableNames !== "function") throw new Error("syncore/schema.ts must default export defineSchema(...).");
|
|
837
896
|
return schema;
|
|
838
897
|
}
|
|
898
|
+
async function loadProjectComponentsManifest(cwd) {
|
|
899
|
+
const filePath = path.join(cwd, "syncore", "components.ts");
|
|
900
|
+
if (!await fileExists(filePath)) return {};
|
|
901
|
+
const manifest = await loadDefaultExport(filePath);
|
|
902
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) throw new Error("syncore/components.ts must default export defineComponents({...}).");
|
|
903
|
+
return manifest;
|
|
904
|
+
}
|
|
905
|
+
async function loadProjectSchema(cwd) {
|
|
906
|
+
const filePath = path.join(cwd, "syncore", "_generated", "schema.ts");
|
|
907
|
+
if (!await fileExists(filePath)) await runCodegen(cwd);
|
|
908
|
+
const schema = await loadDefaultExport(filePath);
|
|
909
|
+
if (!schema || typeof schema !== "object" || typeof schema.tableNames !== "function") throw new Error("syncore/_generated/schema.ts must default export a composed Syncore schema.");
|
|
910
|
+
return schema;
|
|
911
|
+
}
|
|
839
912
|
async function loadDefaultExport(filePath) {
|
|
840
913
|
if (!await fileExists(filePath)) throw new Error(`Missing file: ${path.relative(process.cwd(), filePath)}`);
|
|
841
914
|
const moduleUrl = pathToFileURL(filePath).href;
|
|
@@ -856,10 +929,19 @@ async function loadNamedExport(filePath, exportName) {
|
|
|
856
929
|
return resolvedValue;
|
|
857
930
|
}
|
|
858
931
|
async function loadProjectFunctions(cwd) {
|
|
859
|
-
const
|
|
932
|
+
const filePath = path.join(cwd, "syncore", "_generated", "functions.ts");
|
|
933
|
+
if (!await fileExists(filePath)) await runCodegen(cwd);
|
|
934
|
+
const functions = await loadNamedExport(filePath, "functions");
|
|
860
935
|
if (!functions || typeof functions !== "object") throw new Error("syncore/_generated/functions.ts must export a functions registry.");
|
|
861
936
|
return functions;
|
|
862
937
|
}
|
|
938
|
+
async function loadProjectResolvedComponents(cwd) {
|
|
939
|
+
const filePath = path.join(cwd, "syncore", "_generated", "components.ts");
|
|
940
|
+
if (!await fileExists(filePath)) await runCodegen(cwd);
|
|
941
|
+
const components = await loadNamedExport(filePath, "resolvedComponents");
|
|
942
|
+
if (!Array.isArray(components)) throw new Error("syncore/_generated/components.ts must export resolvedComponents.");
|
|
943
|
+
return components;
|
|
944
|
+
}
|
|
863
945
|
var HubSqliteDriver = class {
|
|
864
946
|
database;
|
|
865
947
|
transactionDepth = 0;
|
|
@@ -1033,8 +1115,11 @@ const hubDevtoolsSqlSupport = {
|
|
|
1033
1115
|
async function createProjectTargetBackend(cwd) {
|
|
1034
1116
|
const projectTarget = resolveProjectTargetConfig(await loadProjectConfig(cwd));
|
|
1035
1117
|
if (!projectTarget) return null;
|
|
1036
|
-
const schema = await
|
|
1037
|
-
|
|
1118
|
+
const [schema, functions, components] = await Promise.all([
|
|
1119
|
+
loadProjectSchema(cwd),
|
|
1120
|
+
loadProjectFunctions(cwd),
|
|
1121
|
+
loadProjectResolvedComponents(cwd)
|
|
1122
|
+
]);
|
|
1038
1123
|
const databasePath = path.resolve(cwd, projectTarget.databasePath);
|
|
1039
1124
|
const storageDirectory = path.resolve(cwd, projectTarget.storageDirectory);
|
|
1040
1125
|
await mkdir(path.dirname(databasePath), { recursive: true });
|
|
@@ -1043,6 +1128,7 @@ async function createProjectTargetBackend(cwd) {
|
|
|
1043
1128
|
const runtime = new SyncoreRuntime({
|
|
1044
1129
|
schema,
|
|
1045
1130
|
functions,
|
|
1131
|
+
components,
|
|
1046
1132
|
driver,
|
|
1047
1133
|
storage: new HubFileStorageAdapter(storageDirectory),
|
|
1048
1134
|
platform: "project"
|
|
@@ -1052,19 +1138,22 @@ async function createProjectTargetBackend(cwd) {
|
|
|
1052
1138
|
driver,
|
|
1053
1139
|
schema,
|
|
1054
1140
|
functions,
|
|
1055
|
-
runtime,
|
|
1141
|
+
admin: runtime.getAdmin(),
|
|
1056
1142
|
sql: hubDevtoolsSqlSupport
|
|
1057
1143
|
});
|
|
1058
1144
|
const subscriptionHost = createDevtoolsSubscriptionHost({
|
|
1059
1145
|
driver,
|
|
1060
1146
|
schema,
|
|
1061
1147
|
functions,
|
|
1062
|
-
runtime,
|
|
1148
|
+
admin: runtime.getAdmin(),
|
|
1063
1149
|
sql: hubDevtoolsSqlSupport
|
|
1064
1150
|
});
|
|
1065
1151
|
return {
|
|
1066
1152
|
hello: {
|
|
1067
1153
|
type: "hello",
|
|
1154
|
+
protocolVersion: SYNCORE_DEVTOOLS_PROTOCOL_VERSION,
|
|
1155
|
+
minSupportedProtocolVersion: SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION,
|
|
1156
|
+
maxSupportedProtocolVersion: SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION,
|
|
1068
1157
|
runtimeId: PROJECT_TARGET_RUNTIME_ID,
|
|
1069
1158
|
platform: "project",
|
|
1070
1159
|
sessionLabel: "Project Target",
|
|
@@ -1239,16 +1328,26 @@ function applyMigrationSql(database, sql, fileName) {
|
|
|
1239
1328
|
async function startDevHub(options) {
|
|
1240
1329
|
const dashboardPort = resolvePortFromEnv("SYNCORE_DASHBOARD_PORT", 4310);
|
|
1241
1330
|
const devtoolsPort = resolvePortFromEnv("SYNCORE_DEVTOOLS_PORT", 4311);
|
|
1331
|
+
const dashboardUrl = `http://localhost:${dashboardPort}`;
|
|
1332
|
+
const devtoolsUrl = `ws://127.0.0.1:${devtoolsPort}`;
|
|
1242
1333
|
const logsDirectory = path.join(options.cwd, ".syncore", "logs");
|
|
1243
1334
|
const logFilePath = path.join(logsDirectory, "runtime.jsonl");
|
|
1335
|
+
const hubAccessToken = sanitizeDevtoolsToken(process.env.SYNCORE_DEVTOOLS_TOKEN) ?? generateDevtoolsToken();
|
|
1336
|
+
const sessionState = {
|
|
1337
|
+
dashboardUrl,
|
|
1338
|
+
authenticatedDashboardUrl: `${dashboardUrl}/?token=${hubAccessToken}`,
|
|
1339
|
+
devtoolsUrl,
|
|
1340
|
+
token: hubAccessToken
|
|
1341
|
+
};
|
|
1244
1342
|
await mkdir(logsDirectory, { recursive: true });
|
|
1245
1343
|
await writeFile(logFilePath, "");
|
|
1246
1344
|
await runDevProjectBootstrap(options.cwd, options.template);
|
|
1247
1345
|
await setupDevProjectWatch(options.cwd, options.template);
|
|
1248
1346
|
if (await isLocalPortInUse(devtoolsPort)) {
|
|
1249
1347
|
console.log(`Syncore devtools hub already running at ws://localhost:${devtoolsPort}. Reusing existing hub/dashboard.`);
|
|
1250
|
-
return;
|
|
1348
|
+
return await readDevtoolsSessionState(options.cwd) ?? sessionState;
|
|
1251
1349
|
}
|
|
1350
|
+
await writeDevtoolsSessionState(options.cwd, sessionState);
|
|
1252
1351
|
let projectTargetBackend = null;
|
|
1253
1352
|
try {
|
|
1254
1353
|
projectTargetBackend = await createProjectTargetBackend(options.cwd);
|
|
@@ -1271,6 +1370,9 @@ async function startDevHub(options) {
|
|
|
1271
1370
|
const dashboardSubscriptions = /* @__PURE__ */ new Map();
|
|
1272
1371
|
const hello = {
|
|
1273
1372
|
type: "hello",
|
|
1373
|
+
protocolVersion: SYNCORE_DEVTOOLS_PROTOCOL_VERSION,
|
|
1374
|
+
minSupportedProtocolVersion: SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION,
|
|
1375
|
+
maxSupportedProtocolVersion: SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION,
|
|
1274
1376
|
runtimeId: "syncore-dev-hub",
|
|
1275
1377
|
platform: "dev"
|
|
1276
1378
|
};
|
|
@@ -1300,7 +1402,18 @@ async function startDevHub(options) {
|
|
|
1300
1402
|
event
|
|
1301
1403
|
})}\n`);
|
|
1302
1404
|
};
|
|
1303
|
-
websocketServer.on("connection", (socket) => {
|
|
1405
|
+
websocketServer.on("connection", (socket, request) => {
|
|
1406
|
+
const isBrowserDashboardClient = isAllowedDashboardOrigin(request.headers.origin, dashboardPort);
|
|
1407
|
+
const isAuthorizedDashboardClient = !isBrowserDashboardClient || isAuthorizedDashboardRequest({
|
|
1408
|
+
requestUrl: request.url,
|
|
1409
|
+
originHeader: request.headers.origin,
|
|
1410
|
+
dashboardPort,
|
|
1411
|
+
expectedToken: hubAccessToken
|
|
1412
|
+
});
|
|
1413
|
+
if (isBrowserDashboardClient && !isAuthorizedDashboardClient) {
|
|
1414
|
+
socket.close(1008, "Unauthorized devtools client");
|
|
1415
|
+
return;
|
|
1416
|
+
}
|
|
1304
1417
|
dashboardSockets.add(socket);
|
|
1305
1418
|
socket.send(JSON.stringify(hello));
|
|
1306
1419
|
for (const runtimeHello of runtimeHellos.values()) socket.send(JSON.stringify(runtimeHello));
|
|
@@ -1318,10 +1431,15 @@ async function startDevHub(options) {
|
|
|
1318
1431
|
if (rawPayload.length === 0) return;
|
|
1319
1432
|
const message = JSON.parse(rawPayload);
|
|
1320
1433
|
if (message.type === "ping") {
|
|
1434
|
+
if (!isAuthorizedDashboardClient) {
|
|
1435
|
+
socket.close(1008, "Unauthorized devtools client");
|
|
1436
|
+
return;
|
|
1437
|
+
}
|
|
1321
1438
|
socket.send(JSON.stringify({ type: "pong" }));
|
|
1322
1439
|
return;
|
|
1323
1440
|
}
|
|
1324
1441
|
if (message.type === "command") {
|
|
1442
|
+
if (!isAuthorizedDashboardClient) return;
|
|
1325
1443
|
const targetRuntimeId = message.targetRuntimeId;
|
|
1326
1444
|
if (!targetRuntimeId) return;
|
|
1327
1445
|
if (targetRuntimeId === PROJECT_TARGET_RUNTIME_ID && projectTargetBackend) {
|
|
@@ -1342,6 +1460,7 @@ async function startDevHub(options) {
|
|
|
1342
1460
|
return;
|
|
1343
1461
|
}
|
|
1344
1462
|
if (message.type === "subscribe") {
|
|
1463
|
+
if (!isAuthorizedDashboardClient) return;
|
|
1345
1464
|
const targetRuntimeId = message.targetRuntimeId;
|
|
1346
1465
|
if (!targetRuntimeId) return;
|
|
1347
1466
|
const subscriptions = dashboardSubscriptions.get(socket) ?? /* @__PURE__ */ new Map();
|
|
@@ -1375,6 +1494,7 @@ async function startDevHub(options) {
|
|
|
1375
1494
|
return;
|
|
1376
1495
|
}
|
|
1377
1496
|
if (message.type === "unsubscribe") {
|
|
1497
|
+
if (!isAuthorizedDashboardClient) return;
|
|
1378
1498
|
const subscriptions = dashboardSubscriptions.get(socket);
|
|
1379
1499
|
const subscription = subscriptions?.get(message.subscriptionId);
|
|
1380
1500
|
if (!subscription) return;
|
|
@@ -1481,25 +1601,29 @@ async function startDevHub(options) {
|
|
|
1481
1601
|
console.error(`Syncore devtools hub failed: ${formatError(error)}`);
|
|
1482
1602
|
process.exit(1);
|
|
1483
1603
|
});
|
|
1484
|
-
|
|
1485
|
-
(
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
const dashboardRoot = path.resolve(CORE_PACKAGE_ROOT, "..", "..", "apps", "dashboard");
|
|
1491
|
-
if (await fileExists(path.join(dashboardRoot, "vite.config.ts"))) try {
|
|
1492
|
-
await (await (await import("vite")).createServer({
|
|
1493
|
-
configFile: path.join(dashboardRoot, "vite.config.ts"),
|
|
1494
|
-
root: dashboardRoot,
|
|
1495
|
-
server: { port: dashboardPort }
|
|
1496
|
-
})).listen();
|
|
1497
|
-
console.log(`Dashboard shell: http://localhost:${dashboardPort}`);
|
|
1498
|
-
} catch (error) {
|
|
1499
|
-
console.log(`Dashboard source not started automatically: ${formatError(error)}`);
|
|
1500
|
-
}
|
|
1501
|
-
})();
|
|
1604
|
+
await new Promise((resolve, reject) => {
|
|
1605
|
+
httpServer.once("error", reject);
|
|
1606
|
+
httpServer.listen(devtoolsPort, "127.0.0.1", () => {
|
|
1607
|
+
httpServer.off("error", reject);
|
|
1608
|
+
resolve();
|
|
1609
|
+
});
|
|
1502
1610
|
});
|
|
1611
|
+
console.log(`Syncore devtools hub: ws://localhost:${devtoolsPort}`);
|
|
1612
|
+
console.log(`Devtools dashboard token: ${hubAccessToken}`);
|
|
1613
|
+
console.log(`Electron/Node runtimes: set devtoolsUrl to ws://localhost:${devtoolsPort}.`);
|
|
1614
|
+
console.log(`Web/Next apps: connect the dashboard or worker bridge to ws://localhost:${devtoolsPort}.`);
|
|
1615
|
+
console.log("Expo apps: use the same hub URL through LAN or adb reverse while developing.");
|
|
1616
|
+
const dashboardRoot = path.resolve(CORE_PACKAGE_ROOT, "..", "..", "apps", "dashboard");
|
|
1617
|
+
if (await fileExists(path.join(dashboardRoot, "vite.config.ts"))) try {
|
|
1618
|
+
await (await (await import("vite")).createServer({
|
|
1619
|
+
configFile: path.join(dashboardRoot, "vite.config.ts"),
|
|
1620
|
+
root: dashboardRoot,
|
|
1621
|
+
server: { port: dashboardPort }
|
|
1622
|
+
})).listen();
|
|
1623
|
+
console.log(`Dashboard shell: ${sessionState.authenticatedDashboardUrl}`);
|
|
1624
|
+
} catch (error) {
|
|
1625
|
+
console.log(`Dashboard source not started automatically: ${formatError(error)}`);
|
|
1626
|
+
}
|
|
1503
1627
|
const close = () => {
|
|
1504
1628
|
projectTargetBackend?.dispose();
|
|
1505
1629
|
websocketServer.close();
|
|
@@ -1508,6 +1632,29 @@ async function startDevHub(options) {
|
|
|
1508
1632
|
};
|
|
1509
1633
|
process.on("SIGINT", close);
|
|
1510
1634
|
process.on("SIGTERM", close);
|
|
1635
|
+
return sessionState;
|
|
1636
|
+
}
|
|
1637
|
+
async function writeDevtoolsSessionState(cwd, state) {
|
|
1638
|
+
const sessionPath = path.join(cwd, DEVTOOLS_SESSION_FILE);
|
|
1639
|
+
await mkdir(path.dirname(sessionPath), { recursive: true });
|
|
1640
|
+
await writeFile(sessionPath, `${JSON.stringify(state, null, 2)}\n`);
|
|
1641
|
+
}
|
|
1642
|
+
async function readDevtoolsSessionState(cwd) {
|
|
1643
|
+
const sessionPath = path.join(cwd, DEVTOOLS_SESSION_FILE);
|
|
1644
|
+
if (!await fileExists(sessionPath)) return null;
|
|
1645
|
+
try {
|
|
1646
|
+
const source = await readFile(sessionPath, "utf8");
|
|
1647
|
+
const parsed = JSON.parse(source);
|
|
1648
|
+
if (typeof parsed.dashboardUrl !== "string" || typeof parsed.authenticatedDashboardUrl !== "string" || typeof parsed.devtoolsUrl !== "string" || typeof parsed.token !== "string") return null;
|
|
1649
|
+
return {
|
|
1650
|
+
dashboardUrl: parsed.dashboardUrl,
|
|
1651
|
+
authenticatedDashboardUrl: parsed.authenticatedDashboardUrl,
|
|
1652
|
+
devtoolsUrl: parsed.devtoolsUrl,
|
|
1653
|
+
token: parsed.token
|
|
1654
|
+
};
|
|
1655
|
+
} catch {
|
|
1656
|
+
return null;
|
|
1657
|
+
}
|
|
1511
1658
|
}
|
|
1512
1659
|
async function setupDevProjectWatch(cwd, template) {
|
|
1513
1660
|
const snapshot = await createDevWatchSnapshot(cwd);
|
|
@@ -1558,6 +1705,10 @@ async function runDevProjectBootstrap(cwd, template) {
|
|
|
1558
1705
|
else console.log("Schema snapshot updated.");
|
|
1559
1706
|
}
|
|
1560
1707
|
for (const warning of plan.warnings) console.warn(`Syncore dev warning: ${warning}`);
|
|
1708
|
+
if (templateUsesConnectedClients(template)) {
|
|
1709
|
+
console.log("Syncore dev is ready. Codegen refreshed; waiting for a connected client runtime to apply schema locally.");
|
|
1710
|
+
return;
|
|
1711
|
+
}
|
|
1561
1712
|
const appliedCount = await applyProjectMigrations(cwd);
|
|
1562
1713
|
console.log(`Syncore dev is ready. Codegen refreshed; ${appliedCount} migration(s) applied.`);
|
|
1563
1714
|
} catch (error) {
|
|
@@ -1644,6 +1795,6 @@ function toSearchValue(value) {
|
|
|
1644
1795
|
return stableStringify(value);
|
|
1645
1796
|
}
|
|
1646
1797
|
//#endregion
|
|
1647
|
-
export { SYNCORE_MIGRATION_SNAPSHOT_FILE_NAME, VALID_SYNCORE_TEMPLATES, applyProjectMigrations, detectProjectTemplate, fileExists, formatError, getNextMigrationNumber, hasSyncoreProject, importJsonlIntoProject, isLocalPortInUse, loadProjectConfig, loadProjectFunctions, loadProjectSchema, logScaffoldResult, readPackageJson, readStoredSnapshot, resolveDefaultSeedFile, resolvePortFromEnv, resolveProjectTargetConfig, resolveRequestedTemplate, runCodegen, runDevProjectBootstrap, runSyncoreCli, scaffoldProject, slugify, startDevHub, writeStoredSnapshot };
|
|
1798
|
+
export { SYNCORE_MIGRATION_SNAPSHOT_FILE_NAME, VALID_SYNCORE_TEMPLATES, applyProjectMigrations, detectProjectTemplate, fileExists, formatError, getNextMigrationNumber, hasSyncoreProject, importJsonlIntoProject, isLocalPortInUse, loadProjectComponentsManifest, loadProjectConfig, loadProjectFunctions, loadProjectResolvedComponents, loadProjectRootSchema, loadProjectSchema, logScaffoldResult, readPackageJson, readStoredSnapshot, resolveDefaultSeedFile, resolvePortFromEnv, resolveProjectTargetConfig, resolveRequestedTemplate, runCodegen, runDevProjectBootstrap, runSyncoreCli, scaffoldProject, slugify, startDevHub, templateUsesConnectedClients, writeStoredSnapshot };
|
|
1648
1799
|
|
|
1649
1800
|
//# sourceMappingURL=cli.mjs.map
|