@jay-framework/stack-server-runtime 0.9.0 → 0.10.0
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/index.d.ts +408 -4
- package/dist/index.js +801 -31
- package/package.json +11 -9
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { AnyJayStackComponentDefinition, PageProps, AnySlowlyRenderResult, UrlParams, JayStackComponentDefinition, AnyFastRenderResult, ServiceMarker } from '@jay-framework/fullstack-component';
|
|
1
|
+
import { AnyJayStackComponentDefinition, PageProps, AnySlowlyRenderResult, UrlParams, JayStackComponentDefinition, AnyFastRenderResult, HttpMethod, CacheOptions, JayAction, JayActionDefinition, ServiceMarker } from '@jay-framework/fullstack-component';
|
|
2
2
|
import { JayComponentCore } from '@jay-framework/component';
|
|
3
3
|
import { ViteDevServer } from 'vite';
|
|
4
4
|
import { JayRoute } from '@jay-framework/stack-route-scanner';
|
|
5
5
|
import { WithValidations } from '@jay-framework/compiler-shared';
|
|
6
6
|
import { JayRollupConfig } from '@jay-framework/rollup-plugin';
|
|
7
|
+
import { TrackByMap } from '@jay-framework/view-state-merge';
|
|
7
8
|
|
|
8
9
|
interface DevServerPagePart {
|
|
9
10
|
compDefinition: AnyJayStackComponentDefinition;
|
|
@@ -11,7 +12,16 @@ interface DevServerPagePart {
|
|
|
11
12
|
clientImport: string;
|
|
12
13
|
clientPart: string;
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
+
interface LoadedPageParts {
|
|
16
|
+
parts: DevServerPagePart[];
|
|
17
|
+
/** TrackBy map for server-side merge (slow → fast) */
|
|
18
|
+
serverTrackByMap?: Record<string, string>;
|
|
19
|
+
/** TrackBy map for client-side merge (fast → interactive) */
|
|
20
|
+
clientTrackByMap?: Record<string, string>;
|
|
21
|
+
/** NPM package names used on this page (for filtering plugin inits) */
|
|
22
|
+
usedPackages: Set<string>;
|
|
23
|
+
}
|
|
24
|
+
declare function loadPageParts(vite: ViteDevServer, route: JayRoute, pagesBase: string, projectBase: string, jayRollupConfig: JayRollupConfig): Promise<WithValidations<LoadedPageParts>>;
|
|
15
25
|
|
|
16
26
|
interface SlowlyChangingPhase {
|
|
17
27
|
runSlowlyForPage(pageParams: object, pageProps: PageProps, parts: Array<DevServerPagePart>): Promise<AnySlowlyRenderResult>;
|
|
@@ -26,7 +36,354 @@ declare function runSlowlyChangingRender<Refs extends object, SlowVS extends obj
|
|
|
26
36
|
|
|
27
37
|
declare function renderFastChangingData(pageParams: object, pageProps: PageProps, carryForward: object, parts: Array<DevServerPagePart>): Promise<AnyFastRenderResult>;
|
|
28
38
|
|
|
29
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Action registry for Jay Stack server-side action handling.
|
|
41
|
+
*
|
|
42
|
+
* Actions are registered at build/startup time and can be invoked via HTTP.
|
|
43
|
+
* The registry maps action names to their definitions (handler, services, method, etc.).
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Registered action entry with resolved metadata.
|
|
48
|
+
*/
|
|
49
|
+
interface RegisteredAction {
|
|
50
|
+
/** Unique action name */
|
|
51
|
+
actionName: string;
|
|
52
|
+
/** HTTP method */
|
|
53
|
+
method: HttpMethod;
|
|
54
|
+
/** Cache options (for GET requests) */
|
|
55
|
+
cacheOptions?: CacheOptions;
|
|
56
|
+
/** Service markers for dependency injection */
|
|
57
|
+
services: any[];
|
|
58
|
+
/** The handler function */
|
|
59
|
+
handler: (input: any, ...services: any[]) => Promise<any>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Result of executing an action.
|
|
63
|
+
*/
|
|
64
|
+
type ActionExecutionResult<T> = {
|
|
65
|
+
success: true;
|
|
66
|
+
data: T;
|
|
67
|
+
} | {
|
|
68
|
+
success: false;
|
|
69
|
+
error: ActionErrorResponse;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Error response structure for failed actions.
|
|
73
|
+
*/
|
|
74
|
+
interface ActionErrorResponse {
|
|
75
|
+
code: string;
|
|
76
|
+
message: string;
|
|
77
|
+
isActionError: boolean;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Registry for Jay Stack server actions.
|
|
81
|
+
*
|
|
82
|
+
* Manages action registration, lookup, and execution.
|
|
83
|
+
* Create instances for testing or use the default export for production.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* // For testing - create isolated instance
|
|
88
|
+
* const registry = new ActionRegistry();
|
|
89
|
+
* registry.register(myAction);
|
|
90
|
+
* const result = await registry.execute('my.action', input);
|
|
91
|
+
*
|
|
92
|
+
* // For production - use default instance
|
|
93
|
+
* import { actionRegistry } from '@jay-framework/stack-server-runtime';
|
|
94
|
+
* actionRegistry.register(myAction);
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
declare class ActionRegistry {
|
|
98
|
+
private readonly actions;
|
|
99
|
+
/**
|
|
100
|
+
* Registers an action with the registry.
|
|
101
|
+
*
|
|
102
|
+
* @param action - The JayAction to register (created via makeJayAction/makeJayQuery)
|
|
103
|
+
*/
|
|
104
|
+
register<I, O, S extends any[]>(action: JayAction<I, O> & JayActionDefinition<I, O, S>): void;
|
|
105
|
+
/**
|
|
106
|
+
* Retrieves a registered action by name.
|
|
107
|
+
*
|
|
108
|
+
* @param actionName - The unique action name
|
|
109
|
+
* @returns The registered action or undefined
|
|
110
|
+
*/
|
|
111
|
+
get(actionName: string): RegisteredAction | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* Checks if an action is registered.
|
|
114
|
+
*
|
|
115
|
+
* @param actionName - The unique action name
|
|
116
|
+
* @returns true if the action is registered
|
|
117
|
+
*/
|
|
118
|
+
has(actionName: string): boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Gets all registered action names.
|
|
121
|
+
*
|
|
122
|
+
* @returns Array of registered action names
|
|
123
|
+
*/
|
|
124
|
+
getNames(): string[];
|
|
125
|
+
/**
|
|
126
|
+
* Clears all registered actions.
|
|
127
|
+
*/
|
|
128
|
+
clear(): void;
|
|
129
|
+
/**
|
|
130
|
+
* Executes a registered action with the given input.
|
|
131
|
+
* Resolves services and calls the handler.
|
|
132
|
+
*
|
|
133
|
+
* @param actionName - The action to execute
|
|
134
|
+
* @param input - The input data for the action
|
|
135
|
+
* @returns The action result or error
|
|
136
|
+
*/
|
|
137
|
+
execute<T = any>(actionName: string, input: unknown): Promise<ActionExecutionResult<T>>;
|
|
138
|
+
/**
|
|
139
|
+
* Gets the cache headers for an action (if applicable).
|
|
140
|
+
*
|
|
141
|
+
* @param actionName - The action name
|
|
142
|
+
* @returns Cache-Control header value or undefined
|
|
143
|
+
*/
|
|
144
|
+
getCacheHeaders(actionName: string): string | undefined;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Default action registry instance.
|
|
148
|
+
* Use this for production; create new instances for testing.
|
|
149
|
+
*/
|
|
150
|
+
declare const actionRegistry: ActionRegistry;
|
|
151
|
+
/**
|
|
152
|
+
* Registers an action with the default registry.
|
|
153
|
+
* @deprecated Use actionRegistry.register() instead
|
|
154
|
+
*/
|
|
155
|
+
declare function registerAction<I, O, S extends any[]>(action: JayAction<I, O> & JayActionDefinition<I, O, S>): void;
|
|
156
|
+
/**
|
|
157
|
+
* Retrieves a registered action by name from the default registry.
|
|
158
|
+
* @deprecated Use actionRegistry.get() instead
|
|
159
|
+
*/
|
|
160
|
+
declare function getRegisteredAction(actionName: string): RegisteredAction | undefined;
|
|
161
|
+
/**
|
|
162
|
+
* Checks if an action is registered in the default registry.
|
|
163
|
+
* @deprecated Use actionRegistry.has() instead
|
|
164
|
+
*/
|
|
165
|
+
declare function hasAction(actionName: string): boolean;
|
|
166
|
+
/**
|
|
167
|
+
* Gets all registered action names from the default registry.
|
|
168
|
+
* @deprecated Use actionRegistry.getNames() instead
|
|
169
|
+
*/
|
|
170
|
+
declare function getRegisteredActionNames(): string[];
|
|
171
|
+
/**
|
|
172
|
+
* Clears all registered actions from the default registry.
|
|
173
|
+
* @deprecated Use actionRegistry.clear() instead
|
|
174
|
+
*/
|
|
175
|
+
declare function clearActionRegistry(): void;
|
|
176
|
+
/**
|
|
177
|
+
* Executes an action from the default registry.
|
|
178
|
+
* @deprecated Use actionRegistry.execute() instead
|
|
179
|
+
*/
|
|
180
|
+
declare function executeAction<T = any>(actionName: string, input: unknown): Promise<ActionExecutionResult<T>>;
|
|
181
|
+
/**
|
|
182
|
+
* Gets cache headers for an action from the default registry.
|
|
183
|
+
* @deprecated Use actionRegistry.getCacheHeaders() instead
|
|
184
|
+
*/
|
|
185
|
+
declare function getActionCacheHeaders(actionName: string): string | undefined;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Action discovery and auto-registration for Jay Stack.
|
|
189
|
+
*
|
|
190
|
+
* Scans project and plugin directories to discover and register actions
|
|
191
|
+
* automatically on server startup.
|
|
192
|
+
*/
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Vite server interface for SSR module loading.
|
|
196
|
+
* Using a minimal interface to avoid direct Vite dependency.
|
|
197
|
+
*/
|
|
198
|
+
interface ViteSSRLoader {
|
|
199
|
+
ssrLoadModule: (url: string) => Promise<Record<string, any>>;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Options for action discovery.
|
|
203
|
+
*/
|
|
204
|
+
interface ActionDiscoveryOptions {
|
|
205
|
+
/** Project root directory */
|
|
206
|
+
projectRoot: string;
|
|
207
|
+
/** Custom actions directory (default: src/actions) */
|
|
208
|
+
actionsDir?: string;
|
|
209
|
+
/** Registry to register actions in (default: global actionRegistry) */
|
|
210
|
+
registry?: ActionRegistry;
|
|
211
|
+
/** Whether to log discovery progress */
|
|
212
|
+
verbose?: boolean;
|
|
213
|
+
/** Vite server for SSR module loading (required in dev for TypeScript files) */
|
|
214
|
+
viteServer?: ViteSSRLoader;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Result of action discovery.
|
|
218
|
+
*/
|
|
219
|
+
interface ActionDiscoveryResult {
|
|
220
|
+
/** Number of actions discovered and registered */
|
|
221
|
+
actionCount: number;
|
|
222
|
+
/** Names of registered actions */
|
|
223
|
+
actionNames: string[];
|
|
224
|
+
/** Paths of scanned action files */
|
|
225
|
+
scannedFiles: string[];
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Discovers and registers actions from the project's actions directory.
|
|
229
|
+
*
|
|
230
|
+
* Scans `src/actions/*.actions.ts` for exported actions and registers them.
|
|
231
|
+
*
|
|
232
|
+
* @param options - Discovery options
|
|
233
|
+
* @returns Result with discovered action information
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```typescript
|
|
237
|
+
* // In dev-server startup
|
|
238
|
+
* const result = await discoverAndRegisterActions({
|
|
239
|
+
* projectRoot: process.cwd(),
|
|
240
|
+
* verbose: true,
|
|
241
|
+
* });
|
|
242
|
+
* console.log(`Registered ${result.actionCount} actions`);
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
declare function discoverAndRegisterActions(options: ActionDiscoveryOptions): Promise<ActionDiscoveryResult>;
|
|
246
|
+
/**
|
|
247
|
+
* Options for discovering plugin actions.
|
|
248
|
+
*/
|
|
249
|
+
interface PluginActionDiscoveryOptions {
|
|
250
|
+
/** Project root directory */
|
|
251
|
+
projectRoot: string;
|
|
252
|
+
/** Registry to register actions in (default: global actionRegistry) */
|
|
253
|
+
registry?: ActionRegistry;
|
|
254
|
+
/** Whether to log discovery progress */
|
|
255
|
+
verbose?: boolean;
|
|
256
|
+
/** Vite server for SSR module loading (required in dev for TypeScript files) */
|
|
257
|
+
viteServer?: ViteSSRLoader;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Discovers and registers actions from all plugins in a project.
|
|
261
|
+
*
|
|
262
|
+
* Scans both local plugins (src/plugins/) and installed NPM plugins.
|
|
263
|
+
*
|
|
264
|
+
* @param options - Discovery options
|
|
265
|
+
* @returns Array of registered action names
|
|
266
|
+
*/
|
|
267
|
+
declare function discoverAllPluginActions(options: PluginActionDiscoveryOptions): Promise<string[]>;
|
|
268
|
+
/**
|
|
269
|
+
* Discovers actions from a single plugin's plugin.yaml file.
|
|
270
|
+
*
|
|
271
|
+
* Reads plugin.yaml, finds the `actions` array, and imports those
|
|
272
|
+
* named exports from the plugin's module.
|
|
273
|
+
*
|
|
274
|
+
* @param pluginPath - Path to the plugin directory (containing plugin.yaml)
|
|
275
|
+
* @param projectRoot - Project root for resolving imports
|
|
276
|
+
* @param registry - Registry to register actions in
|
|
277
|
+
* @param verbose - Whether to log progress
|
|
278
|
+
* @returns Array of registered action names
|
|
279
|
+
*/
|
|
280
|
+
declare function discoverPluginActions(pluginPath: string, projectRoot: string, registry?: ActionRegistry, verbose?: boolean, viteServer?: ViteSSRLoader): Promise<string[]>;
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Plugin initialization discovery and execution for Jay Stack.
|
|
284
|
+
*
|
|
285
|
+
* Discovers plugins with init configurations (using makeJayInit pattern),
|
|
286
|
+
* sorts them by dependencies, and executes their init functions in order.
|
|
287
|
+
*
|
|
288
|
+
* Auto-discovers `lib/init.ts` files in plugins, or uses the path specified
|
|
289
|
+
* in `plugin.yaml` via the `init` property.
|
|
290
|
+
*/
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Information about a discovered plugin with init.
|
|
294
|
+
*/
|
|
295
|
+
interface PluginWithInit {
|
|
296
|
+
/** Plugin name from plugin.yaml (used as default init key) */
|
|
297
|
+
name: string;
|
|
298
|
+
/** Plugin path (directory containing plugin.yaml) */
|
|
299
|
+
pluginPath: string;
|
|
300
|
+
/** Package name for NPM plugins, or path for local plugins */
|
|
301
|
+
packageName: string;
|
|
302
|
+
/** Whether this is a local plugin (src/plugins/) or NPM */
|
|
303
|
+
isLocal: boolean;
|
|
304
|
+
/**
|
|
305
|
+
* Init module path relative to plugin root.
|
|
306
|
+
* Default is 'lib/init' (auto-discovered).
|
|
307
|
+
* Can be overridden via `init` property in plugin.yaml.
|
|
308
|
+
*/
|
|
309
|
+
initModule: string;
|
|
310
|
+
/**
|
|
311
|
+
* Export name for the init constant.
|
|
312
|
+
* Default is 'init'.
|
|
313
|
+
* Can be overridden via `init` property in plugin.yaml (for compiled packages).
|
|
314
|
+
*/
|
|
315
|
+
initExport: string;
|
|
316
|
+
/** Dependencies from package.json (for ordering) */
|
|
317
|
+
dependencies: string[];
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Options for plugin init discovery.
|
|
321
|
+
*/
|
|
322
|
+
interface PluginInitDiscoveryOptions {
|
|
323
|
+
/** Project root directory */
|
|
324
|
+
projectRoot: string;
|
|
325
|
+
/** Whether to log discovery progress */
|
|
326
|
+
verbose?: boolean;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Discovers all plugins with init configurations.
|
|
330
|
+
*
|
|
331
|
+
* Auto-discovers `lib/init.ts` files in plugins, or uses the path specified
|
|
332
|
+
* in `plugin.yaml` via the `init` property.
|
|
333
|
+
*
|
|
334
|
+
* Scans both local plugins (src/plugins/) and NPM plugins (node_modules/).
|
|
335
|
+
*/
|
|
336
|
+
declare function discoverPluginsWithInit(options: PluginInitDiscoveryOptions): Promise<PluginWithInit[]>;
|
|
337
|
+
/**
|
|
338
|
+
* Sorts plugins by their dependencies (topological sort).
|
|
339
|
+
* Plugins with no dependencies come first, then plugins that depend on them, etc.
|
|
340
|
+
*/
|
|
341
|
+
declare function sortPluginsByDependencies(plugins: PluginWithInit[]): PluginWithInit[];
|
|
342
|
+
/**
|
|
343
|
+
* Executes server init for all plugins in order.
|
|
344
|
+
*
|
|
345
|
+
* Uses the `makeJayInit` pattern:
|
|
346
|
+
* - Loads the init module and finds the JayInit object
|
|
347
|
+
* - Calls `_serverInit()` if defined
|
|
348
|
+
* - Stores returned data via `setClientInitData(pluginName, data)`
|
|
349
|
+
*
|
|
350
|
+
* @param plugins - Sorted list of plugins with init
|
|
351
|
+
* @param viteServer - Vite server for SSR module loading (optional)
|
|
352
|
+
* @param verbose - Whether to log progress
|
|
353
|
+
*/
|
|
354
|
+
declare function executePluginServerInits(plugins: PluginWithInit[], viteServer?: ViteSSRLoader, verbose?: boolean): Promise<void>;
|
|
355
|
+
/**
|
|
356
|
+
* Information needed to generate client init script for a plugin.
|
|
357
|
+
*/
|
|
358
|
+
interface PluginClientInitInfo {
|
|
359
|
+
/** Plugin name (used for logging and as data key) */
|
|
360
|
+
name: string;
|
|
361
|
+
/** Import path for the init module */
|
|
362
|
+
importPath: string;
|
|
363
|
+
/** Export name for the JayInit constant */
|
|
364
|
+
initExport: string;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Prepares plugin information for client init script generation.
|
|
368
|
+
*
|
|
369
|
+
* For LOCAL plugins: Use the init file path directly
|
|
370
|
+
* For NPM plugins: Use the `/client` subpath (client bundle exports init)
|
|
371
|
+
*
|
|
372
|
+
* Filters to only plugins that have init modules and returns the
|
|
373
|
+
* information needed to generate client-side imports and execution.
|
|
374
|
+
*/
|
|
375
|
+
declare function preparePluginClientInits(plugins: PluginWithInit[]): PluginClientInitInfo[];
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Information needed to generate client init script for the project.
|
|
379
|
+
*/
|
|
380
|
+
interface ProjectClientInitInfo {
|
|
381
|
+
/** Import path for the init module */
|
|
382
|
+
importPath: string;
|
|
383
|
+
/** Export name for the JayInit constant (default: 'init') */
|
|
384
|
+
initExport?: string;
|
|
385
|
+
}
|
|
386
|
+
declare function generateClientScript(defaultViewState: object, fastCarryForward: object, parts: DevServerPagePart[], jayHtmlPath: string, trackByMap?: TrackByMap, clientInitData?: Record<string, Record<string, any>>, projectInit?: ProjectClientInitInfo, pluginInits?: PluginClientInitInfo[]): string;
|
|
30
387
|
|
|
31
388
|
/**
|
|
32
389
|
* Service registry for Jay Stack server-side dependency injection.
|
|
@@ -144,5 +501,52 @@ declare function runShutdownCallbacks(): Promise<void>;
|
|
|
144
501
|
* Internal API used by dev-server during hot reload.
|
|
145
502
|
*/
|
|
146
503
|
declare function clearLifecycleCallbacks(): void;
|
|
504
|
+
/**
|
|
505
|
+
* Sets client init data for a specific namespace (plugin or project).
|
|
506
|
+
* Each namespace's data is kept separate and passed only to the matching
|
|
507
|
+
* client init callback.
|
|
508
|
+
*
|
|
509
|
+
* @param key - Namespace key (plugin name or 'project')
|
|
510
|
+
* @param data - Data object for this namespace
|
|
511
|
+
*
|
|
512
|
+
* @example
|
|
513
|
+
* ```typescript
|
|
514
|
+
* // In plugin server init
|
|
515
|
+
* onInit(async () => {
|
|
516
|
+
* setClientInitData('wix-stores', {
|
|
517
|
+
* currency: 'USD',
|
|
518
|
+
* apiEndpoint: process.env.STORES_API_URL,
|
|
519
|
+
* });
|
|
520
|
+
* });
|
|
521
|
+
*
|
|
522
|
+
* // In project jay.init.ts
|
|
523
|
+
* onInit(async () => {
|
|
524
|
+
* setClientInitData('project', {
|
|
525
|
+
* oauthClientId: process.env.OAUTH_CLIENT_ID,
|
|
526
|
+
* featureFlags: await loadFeatureFlags(),
|
|
527
|
+
* });
|
|
528
|
+
* });
|
|
529
|
+
* ```
|
|
530
|
+
*/
|
|
531
|
+
declare function setClientInitData(key: string, data: Record<string, any>): void;
|
|
532
|
+
/**
|
|
533
|
+
* Gets all namespaced client init data.
|
|
534
|
+
* Internal API used by page rendering to embed data in HTML.
|
|
535
|
+
*
|
|
536
|
+
* @returns Object with namespace keys and their data
|
|
537
|
+
*/
|
|
538
|
+
declare function getClientInitData(): Record<string, Record<string, any>>;
|
|
539
|
+
/**
|
|
540
|
+
* Gets client init data for a specific namespace.
|
|
541
|
+
*
|
|
542
|
+
* @param key - Namespace key
|
|
543
|
+
* @returns Data for that namespace, or empty object if not set
|
|
544
|
+
*/
|
|
545
|
+
declare function getClientInitDataForKey(key: string): Record<string, any>;
|
|
546
|
+
/**
|
|
547
|
+
* Clears client init data.
|
|
548
|
+
* Internal API used by dev-server during hot reload.
|
|
549
|
+
*/
|
|
550
|
+
declare function clearClientInitData(): void;
|
|
147
551
|
|
|
148
|
-
export { DevSlowlyChangingPhase, type SlowlyChangingPhase, clearLifecycleCallbacks, clearServiceRegistry, generateClientScript, getService, hasService, loadPageParts, onInit, onShutdown, registerService, renderFastChangingData, resolveServices, runInitCallbacks, runLoadParams, runShutdownCallbacks, runSlowlyChangingRender };
|
|
552
|
+
export { type ActionDiscoveryOptions, type ActionDiscoveryResult, type ActionErrorResponse, type ActionExecutionResult, ActionRegistry, type DevServerPagePart, DevSlowlyChangingPhase, type LoadedPageParts, type PluginActionDiscoveryOptions, type PluginClientInitInfo, type PluginInitDiscoveryOptions, type PluginWithInit, type ProjectClientInitInfo, type RegisteredAction, type SlowlyChangingPhase, type ViteSSRLoader, actionRegistry, clearActionRegistry, clearClientInitData, clearLifecycleCallbacks, clearServiceRegistry, discoverAllPluginActions, discoverAndRegisterActions, discoverPluginActions, discoverPluginsWithInit, executeAction, executePluginServerInits, generateClientScript, getActionCacheHeaders, getClientInitData, getClientInitDataForKey, getRegisteredAction, getRegisteredActionNames, getService, hasAction, hasService, loadPageParts, onInit, onShutdown, preparePluginClientInits, registerAction, registerService, renderFastChangingData, resolveServices, runInitCallbacks, runLoadParams, runShutdownCallbacks, runSlowlyChangingRender, setClientInitData, sortPluginsByDependencies };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => {
|
|
4
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
+
return value;
|
|
6
|
+
};
|
|
7
|
+
import { notFound, partialRender, phaseOutput, isJayAction } from "@jay-framework/fullstack-component";
|
|
8
|
+
import fs$1 from "node:fs/promises";
|
|
9
|
+
import * as path from "node:path";
|
|
10
|
+
import path__default from "node:path";
|
|
11
|
+
import { parseJayFile, JAY_IMPORT_RESOLVER } from "@jay-framework/compiler-jay-html";
|
|
5
12
|
import { createRequire } from "module";
|
|
13
|
+
import * as fs from "node:fs";
|
|
14
|
+
import { createRequire as createRequire$1 } from "node:module";
|
|
15
|
+
import "prettier";
|
|
16
|
+
import "js-beautify";
|
|
17
|
+
import fs$2 from "fs";
|
|
18
|
+
import path$1 from "path";
|
|
19
|
+
import YAML from "yaml";
|
|
6
20
|
const serviceRegistry = /* @__PURE__ */ new Map();
|
|
7
21
|
function registerService(marker, service) {
|
|
8
22
|
serviceRegistry.set(marker, service);
|
|
@@ -50,6 +64,19 @@ function clearLifecycleCallbacks() {
|
|
|
50
64
|
initCallbacks.length = 0;
|
|
51
65
|
shutdownCallbacks.length = 0;
|
|
52
66
|
}
|
|
67
|
+
let clientInitData = {};
|
|
68
|
+
function setClientInitData(key, data) {
|
|
69
|
+
clientInitData[key] = { ...clientInitData[key] || {}, ...data };
|
|
70
|
+
}
|
|
71
|
+
function getClientInitData() {
|
|
72
|
+
return clientInitData;
|
|
73
|
+
}
|
|
74
|
+
function getClientInitDataForKey(key) {
|
|
75
|
+
return clientInitData[key] || {};
|
|
76
|
+
}
|
|
77
|
+
function clearClientInitData() {
|
|
78
|
+
clientInitData = {};
|
|
79
|
+
}
|
|
53
80
|
function isLeftSideParamsSubsetOfRightSideParams(left, right) {
|
|
54
81
|
return Object.keys(left).reduce((prev, curr) => prev && left[curr] === right[curr], true);
|
|
55
82
|
}
|
|
@@ -84,7 +111,7 @@ class DevSlowlyChangingPhase {
|
|
|
84
111
|
{ ...pageProps, ...pageParams },
|
|
85
112
|
...services
|
|
86
113
|
);
|
|
87
|
-
if (slowlyRenderedPart.kind === "
|
|
114
|
+
if (slowlyRenderedPart.kind === "PhaseOutput") {
|
|
88
115
|
if (!key) {
|
|
89
116
|
slowlyViewState = { ...slowlyViewState, ...slowlyRenderedPart.rendered };
|
|
90
117
|
carryForward = { ...carryForward, ...slowlyRenderedPart.carryForward };
|
|
@@ -117,7 +144,7 @@ async function renderFastChangingData(pageParams, pageProps, carryForward, parts
|
|
|
117
144
|
partSlowlyCarryForward,
|
|
118
145
|
...services
|
|
119
146
|
);
|
|
120
|
-
if (fastRenderedPart.kind === "
|
|
147
|
+
if (fastRenderedPart.kind === "PhaseOutput") {
|
|
121
148
|
if (!key) {
|
|
122
149
|
fastViewState = { ...fastViewState, ...fastRenderedPart.rendered };
|
|
123
150
|
fastCarryForward = { ...fastCarryForward, ...fastRenderedPart.carryForward };
|
|
@@ -129,13 +156,37 @@ async function renderFastChangingData(pageParams, pageProps, carryForward, parts
|
|
|
129
156
|
return fastRenderedPart;
|
|
130
157
|
}
|
|
131
158
|
}
|
|
132
|
-
return Promise.resolve(
|
|
159
|
+
return Promise.resolve(phaseOutput(fastViewState, fastCarryForward));
|
|
133
160
|
}
|
|
134
|
-
function generateClientScript(defaultViewState, fastCarryForward, parts, jayHtmlPath) {
|
|
161
|
+
function generateClientScript(defaultViewState, fastCarryForward, parts, jayHtmlPath, trackByMap = {}, clientInitData2 = {}, projectInit, pluginInits = []) {
|
|
135
162
|
const imports = parts.length > 0 ? parts.map((part) => part.clientImport).join("\n") + "\n" : "";
|
|
136
163
|
const compositeParts = parts.length > 0 ? `[
|
|
137
164
|
${parts.map((part) => " " + part.clientPart).join(",\n")}
|
|
138
165
|
]` : "[]";
|
|
166
|
+
const hasClientInit = projectInit || pluginInits.length > 0;
|
|
167
|
+
const pluginClientInitImports = pluginInits.map((plugin, idx) => {
|
|
168
|
+
return `import { ${plugin.initExport} as jayInit${idx} } from "${plugin.importPath}";`;
|
|
169
|
+
}).join("\n ");
|
|
170
|
+
const projectInitImport = projectInit ? `import { ${projectInit.initExport || "init"} as projectJayInit } from "${projectInit.importPath}";` : "";
|
|
171
|
+
const pluginClientInitCalls = pluginInits.map((plugin, idx) => {
|
|
172
|
+
const pluginData = clientInitData2[plugin.name] || {};
|
|
173
|
+
return `if (typeof jayInit${idx}._clientInit === 'function') {
|
|
174
|
+
console.log('[DevServer] Running client init: ${plugin.name}');
|
|
175
|
+
await jayInit${idx}._clientInit(${JSON.stringify(pluginData)});
|
|
176
|
+
}`;
|
|
177
|
+
}).join("\n ");
|
|
178
|
+
const projectInitCall = projectInit ? `if (typeof projectJayInit._clientInit === 'function') {
|
|
179
|
+
console.log('[DevServer] Running client init: project');
|
|
180
|
+
const projectData = ${JSON.stringify(clientInitData2["project"] || {})};
|
|
181
|
+
await projectJayInit._clientInit(projectData);
|
|
182
|
+
}` : "";
|
|
183
|
+
const clientInitExecution = hasClientInit ? `
|
|
184
|
+
// Plugin client initialization (in dependency order)
|
|
185
|
+
${pluginClientInitCalls}
|
|
186
|
+
|
|
187
|
+
// Project client initialization
|
|
188
|
+
${projectInitCall}
|
|
189
|
+
` : "";
|
|
139
190
|
return `<!doctype html>
|
|
140
191
|
<html lang="en">
|
|
141
192
|
<head>
|
|
@@ -147,13 +198,16 @@ ${parts.map((part) => " " + part.clientPart).join(",\n")}
|
|
|
147
198
|
<div id="target"></div>
|
|
148
199
|
<script type="module">
|
|
149
200
|
import {makeCompositeJayComponent} from "@jay-framework/stack-client-runtime";
|
|
201
|
+
${pluginClientInitImports}
|
|
202
|
+
${projectInitImport}
|
|
150
203
|
import { render } from '${jayHtmlPath}';
|
|
151
204
|
${imports}
|
|
152
205
|
const viewState = ${JSON.stringify(defaultViewState)};
|
|
153
206
|
const fastCarryForward = ${JSON.stringify(fastCarryForward)};
|
|
154
|
-
|
|
207
|
+
const trackByMap = ${JSON.stringify(trackByMap)};
|
|
208
|
+
${clientInitExecution}
|
|
155
209
|
const target = document.getElementById('target');
|
|
156
|
-
const pageComp = makeCompositeJayComponent(render, viewState, fastCarryForward, ${compositeParts})
|
|
210
|
+
const pageComp = makeCompositeJayComponent(render, viewState, fastCarryForward, ${compositeParts}, trackByMap)
|
|
157
211
|
|
|
158
212
|
const instance = pageComp({...viewState, ...fastCarryForward})
|
|
159
213
|
target.appendChild(instance.element.dom);
|
|
@@ -161,24 +215,22 @@ ${parts.map((part) => " " + part.clientPart).join(",\n")}
|
|
|
161
215
|
</body>
|
|
162
216
|
</html>`;
|
|
163
217
|
}
|
|
164
|
-
const
|
|
165
|
-
async function loadPageParts(vite, route, pagesBase, jayRollupConfig) {
|
|
166
|
-
const exists = await fs.access(route.compPath, fs.constants.F_OK).then(() => true).catch(() => false);
|
|
218
|
+
const require$2 = createRequire(import.meta.url);
|
|
219
|
+
async function loadPageParts(vite, route, pagesBase, projectBase, jayRollupConfig) {
|
|
220
|
+
const exists = await fs$1.access(route.compPath, fs$1.constants.F_OK).then(() => true).catch(() => false);
|
|
167
221
|
const parts = [];
|
|
168
222
|
if (exists) {
|
|
169
|
-
const pageComponent = (await vite.ssrLoadModule(route.compPath
|
|
223
|
+
const pageComponent = (await vite.ssrLoadModule(route.compPath)).page;
|
|
170
224
|
parts.push({
|
|
171
225
|
compDefinition: pageComponent,
|
|
172
226
|
// Client import uses client-only code (server code stripped)
|
|
173
|
-
clientImport: `import {page} from '${route.compPath}
|
|
227
|
+
clientImport: `import {page} from '${route.compPath}'`,
|
|
174
228
|
clientPart: `{comp: page.comp, contextMarkers: []}`
|
|
175
229
|
});
|
|
176
230
|
}
|
|
177
|
-
const jayHtmlSource = (await fs.readFile(route.jayHtmlPath)).toString();
|
|
178
|
-
const fileName =
|
|
179
|
-
const dirName =
|
|
180
|
-
const module = await import("@jay-framework/compiler-jay-html");
|
|
181
|
-
const JAY_IMPORT_RESOLVER = module.JAY_IMPORT_RESOLVER;
|
|
231
|
+
const jayHtmlSource = (await fs$1.readFile(route.jayHtmlPath)).toString();
|
|
232
|
+
const fileName = path__default.basename(route.jayHtmlPath);
|
|
233
|
+
const dirName = path__default.dirname(route.jayHtmlPath);
|
|
182
234
|
const jayHtmlWithValidations = await parseJayFile(
|
|
183
235
|
jayHtmlSource,
|
|
184
236
|
fileName,
|
|
@@ -186,19 +238,24 @@ async function loadPageParts(vite, route, pagesBase, jayRollupConfig) {
|
|
|
186
238
|
{
|
|
187
239
|
relativePath: jayRollupConfig.tsConfigFilePath
|
|
188
240
|
},
|
|
189
|
-
JAY_IMPORT_RESOLVER
|
|
241
|
+
JAY_IMPORT_RESOLVER,
|
|
242
|
+
projectBase
|
|
190
243
|
);
|
|
191
244
|
return jayHtmlWithValidations.mapAsync(async (jayHtml) => {
|
|
245
|
+
const usedPackages = /* @__PURE__ */ new Set();
|
|
192
246
|
for await (const headlessImport of jayHtml.headlessImports) {
|
|
193
|
-
const
|
|
247
|
+
const module = headlessImport.codeLink.module;
|
|
194
248
|
const name = headlessImport.codeLink.names[0].name;
|
|
195
|
-
const isLocalModule =
|
|
196
|
-
const modulePath = isLocalModule ?
|
|
197
|
-
const
|
|
198
|
-
const
|
|
199
|
-
const
|
|
200
|
-
const
|
|
201
|
-
|
|
249
|
+
const isLocalModule = module[0] === "." || module[0] === "/";
|
|
250
|
+
const modulePath = isLocalModule ? path__default.resolve(dirName, module) : require$2.resolve(module, { paths: require$2.resolve.paths(dirName) });
|
|
251
|
+
const compDefinition = (await vite.ssrLoadModule(modulePath))[name];
|
|
252
|
+
const moduleImport = isLocalModule ? path__default.resolve(dirName, module) : module;
|
|
253
|
+
const isNpmPackage = !isLocalModule;
|
|
254
|
+
const clientModuleImport = isNpmPackage ? `${moduleImport}/client` : `${moduleImport}`;
|
|
255
|
+
if (isNpmPackage) {
|
|
256
|
+
const packageName = module.startsWith("@") ? module.split("/").slice(0, 2).join("/") : module.split("/")[0];
|
|
257
|
+
usedPackages.add(packageName);
|
|
258
|
+
}
|
|
202
259
|
const key = headlessImport.key;
|
|
203
260
|
const part = {
|
|
204
261
|
key,
|
|
@@ -208,24 +265,737 @@ async function loadPageParts(vite, route, pagesBase, jayRollupConfig) {
|
|
|
208
265
|
};
|
|
209
266
|
parts.push(part);
|
|
210
267
|
}
|
|
211
|
-
return
|
|
268
|
+
return {
|
|
269
|
+
parts,
|
|
270
|
+
serverTrackByMap: jayHtml.serverTrackByMap,
|
|
271
|
+
clientTrackByMap: jayHtml.clientTrackByMap,
|
|
272
|
+
usedPackages
|
|
273
|
+
};
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
class ActionRegistry {
|
|
277
|
+
constructor() {
|
|
278
|
+
__publicField(this, "actions", /* @__PURE__ */ new Map());
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Registers an action with the registry.
|
|
282
|
+
*
|
|
283
|
+
* @param action - The JayAction to register (created via makeJayAction/makeJayQuery)
|
|
284
|
+
*/
|
|
285
|
+
register(action) {
|
|
286
|
+
const entry = {
|
|
287
|
+
actionName: action.actionName,
|
|
288
|
+
method: action.method,
|
|
289
|
+
cacheOptions: action.cacheOptions,
|
|
290
|
+
services: action.services,
|
|
291
|
+
handler: action.handler
|
|
292
|
+
};
|
|
293
|
+
this.actions.set(action.actionName, entry);
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Retrieves a registered action by name.
|
|
297
|
+
*
|
|
298
|
+
* @param actionName - The unique action name
|
|
299
|
+
* @returns The registered action or undefined
|
|
300
|
+
*/
|
|
301
|
+
get(actionName) {
|
|
302
|
+
return this.actions.get(actionName);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Checks if an action is registered.
|
|
306
|
+
*
|
|
307
|
+
* @param actionName - The unique action name
|
|
308
|
+
* @returns true if the action is registered
|
|
309
|
+
*/
|
|
310
|
+
has(actionName) {
|
|
311
|
+
return this.actions.has(actionName);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Gets all registered action names.
|
|
315
|
+
*
|
|
316
|
+
* @returns Array of registered action names
|
|
317
|
+
*/
|
|
318
|
+
getNames() {
|
|
319
|
+
return Array.from(this.actions.keys());
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Clears all registered actions.
|
|
323
|
+
*/
|
|
324
|
+
clear() {
|
|
325
|
+
this.actions.clear();
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Executes a registered action with the given input.
|
|
329
|
+
* Resolves services and calls the handler.
|
|
330
|
+
*
|
|
331
|
+
* @param actionName - The action to execute
|
|
332
|
+
* @param input - The input data for the action
|
|
333
|
+
* @returns The action result or error
|
|
334
|
+
*/
|
|
335
|
+
async execute(actionName, input) {
|
|
336
|
+
const action = this.actions.get(actionName);
|
|
337
|
+
if (!action) {
|
|
338
|
+
return {
|
|
339
|
+
success: false,
|
|
340
|
+
error: {
|
|
341
|
+
code: "ACTION_NOT_FOUND",
|
|
342
|
+
message: `Action '${actionName}' is not registered`,
|
|
343
|
+
isActionError: false
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
try {
|
|
348
|
+
const services = resolveServices(action.services);
|
|
349
|
+
const result = await action.handler(input, ...services);
|
|
350
|
+
return {
|
|
351
|
+
success: true,
|
|
352
|
+
data: result
|
|
353
|
+
};
|
|
354
|
+
} catch (error) {
|
|
355
|
+
if (error && typeof error === "object" && "code" in error && "message" in error) {
|
|
356
|
+
const actionError = error;
|
|
357
|
+
if (actionError.name === "ActionError") {
|
|
358
|
+
return {
|
|
359
|
+
success: false,
|
|
360
|
+
error: {
|
|
361
|
+
code: actionError.code,
|
|
362
|
+
message: actionError.message,
|
|
363
|
+
isActionError: true
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
const message = error instanceof Error ? error.message : "Unknown error occurred";
|
|
369
|
+
return {
|
|
370
|
+
success: false,
|
|
371
|
+
error: {
|
|
372
|
+
code: "INTERNAL_ERROR",
|
|
373
|
+
message,
|
|
374
|
+
isActionError: false
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Gets the cache headers for an action (if applicable).
|
|
381
|
+
*
|
|
382
|
+
* @param actionName - The action name
|
|
383
|
+
* @returns Cache-Control header value or undefined
|
|
384
|
+
*/
|
|
385
|
+
getCacheHeaders(actionName) {
|
|
386
|
+
const action = this.actions.get(actionName);
|
|
387
|
+
if (!action || action.method !== "GET" || !action.cacheOptions) {
|
|
388
|
+
return void 0;
|
|
389
|
+
}
|
|
390
|
+
const { maxAge, staleWhileRevalidate } = action.cacheOptions;
|
|
391
|
+
const parts = [];
|
|
392
|
+
if (maxAge !== void 0) {
|
|
393
|
+
parts.push(`max-age=${maxAge}`);
|
|
394
|
+
}
|
|
395
|
+
if (staleWhileRevalidate !== void 0) {
|
|
396
|
+
parts.push(`stale-while-revalidate=${staleWhileRevalidate}`);
|
|
397
|
+
}
|
|
398
|
+
return parts.length > 0 ? parts.join(", ") : void 0;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
const actionRegistry = new ActionRegistry();
|
|
402
|
+
function registerAction(action) {
|
|
403
|
+
actionRegistry.register(action);
|
|
404
|
+
}
|
|
405
|
+
function getRegisteredAction(actionName) {
|
|
406
|
+
return actionRegistry.get(actionName);
|
|
407
|
+
}
|
|
408
|
+
function hasAction(actionName) {
|
|
409
|
+
return actionRegistry.has(actionName);
|
|
410
|
+
}
|
|
411
|
+
function getRegisteredActionNames() {
|
|
412
|
+
return actionRegistry.getNames();
|
|
413
|
+
}
|
|
414
|
+
function clearActionRegistry() {
|
|
415
|
+
actionRegistry.clear();
|
|
416
|
+
}
|
|
417
|
+
async function executeAction(actionName, input) {
|
|
418
|
+
return actionRegistry.execute(actionName, input);
|
|
419
|
+
}
|
|
420
|
+
function getActionCacheHeaders(actionName) {
|
|
421
|
+
return actionRegistry.getCacheHeaders(actionName);
|
|
422
|
+
}
|
|
423
|
+
var __defProp2 = Object.defineProperty;
|
|
424
|
+
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
425
|
+
var __publicField2 = (obj, key, value) => {
|
|
426
|
+
__defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
427
|
+
return value;
|
|
428
|
+
};
|
|
429
|
+
class JayAtomicType {
|
|
430
|
+
constructor(name) {
|
|
431
|
+
__publicField2(this, "kind", 0);
|
|
432
|
+
this.name = name;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
new JayAtomicType("string");
|
|
436
|
+
new JayAtomicType("number");
|
|
437
|
+
new JayAtomicType("boolean");
|
|
438
|
+
new JayAtomicType("Date");
|
|
439
|
+
new JayAtomicType("Unknown");
|
|
440
|
+
class JayObjectType {
|
|
441
|
+
constructor(name, props) {
|
|
442
|
+
__publicField2(this, "kind", 8);
|
|
443
|
+
this.name = name;
|
|
444
|
+
this.props = props;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
new JayObjectType("Error", {
|
|
448
|
+
message: new JayAtomicType("string"),
|
|
449
|
+
name: new JayAtomicType("string"),
|
|
450
|
+
stack: new JayAtomicType("string")
|
|
451
|
+
});
|
|
452
|
+
var RuntimeMode = /* @__PURE__ */ ((RuntimeMode2) => {
|
|
453
|
+
RuntimeMode2["MainTrusted"] = "mainTrusted";
|
|
454
|
+
RuntimeMode2["MainSandbox"] = "mainSandbox";
|
|
455
|
+
RuntimeMode2["WorkerTrusted"] = "workerTrusted";
|
|
456
|
+
RuntimeMode2["WorkerSandbox"] = "workerSandbox";
|
|
457
|
+
return RuntimeMode2;
|
|
458
|
+
})(RuntimeMode || {});
|
|
459
|
+
const TS_EXTENSION = ".ts";
|
|
460
|
+
const JAY_QUERY_PREFIX = "?jay-";
|
|
461
|
+
[
|
|
462
|
+
// Build environments
|
|
463
|
+
{
|
|
464
|
+
pattern: `${JAY_QUERY_PREFIX}${"client"}`,
|
|
465
|
+
buildEnv: "client"
|
|
466
|
+
/* Client */
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
pattern: `${JAY_QUERY_PREFIX}${"server"}`,
|
|
470
|
+
buildEnv: "server"
|
|
471
|
+
/* Server */
|
|
472
|
+
},
|
|
473
|
+
// Runtime modes (with .ts suffix)
|
|
474
|
+
{
|
|
475
|
+
pattern: `${JAY_QUERY_PREFIX}${RuntimeMode.MainSandbox}${TS_EXTENSION}`,
|
|
476
|
+
runtimeMode: RuntimeMode.MainSandbox
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
pattern: `${JAY_QUERY_PREFIX}${RuntimeMode.WorkerTrusted}${TS_EXTENSION}`,
|
|
480
|
+
runtimeMode: RuntimeMode.WorkerTrusted
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
pattern: `${JAY_QUERY_PREFIX}${RuntimeMode.WorkerSandbox}${TS_EXTENSION}`,
|
|
484
|
+
runtimeMode: RuntimeMode.WorkerSandbox
|
|
485
|
+
},
|
|
486
|
+
// Runtime modes (without .ts suffix)
|
|
487
|
+
{
|
|
488
|
+
pattern: `${JAY_QUERY_PREFIX}${RuntimeMode.MainSandbox}`,
|
|
489
|
+
runtimeMode: RuntimeMode.MainSandbox
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
pattern: `${JAY_QUERY_PREFIX}${RuntimeMode.WorkerTrusted}`,
|
|
493
|
+
runtimeMode: RuntimeMode.WorkerTrusted
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
pattern: `${JAY_QUERY_PREFIX}${RuntimeMode.WorkerSandbox}`,
|
|
497
|
+
runtimeMode: RuntimeMode.WorkerSandbox
|
|
498
|
+
}
|
|
499
|
+
];
|
|
500
|
+
createRequire(import.meta.url);
|
|
501
|
+
function loadPluginManifest(pluginDir) {
|
|
502
|
+
const pluginYamlPath = path$1.join(pluginDir, "plugin.yaml");
|
|
503
|
+
if (!fs$2.existsSync(pluginYamlPath)) {
|
|
504
|
+
return null;
|
|
505
|
+
}
|
|
506
|
+
try {
|
|
507
|
+
const yamlContent = fs$2.readFileSync(pluginYamlPath, "utf-8");
|
|
508
|
+
return YAML.parse(yamlContent);
|
|
509
|
+
} catch (error) {
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
const s = createRequire(import.meta.url), e = s("typescript");
|
|
514
|
+
new Proxy(e, {
|
|
515
|
+
get(t, r) {
|
|
516
|
+
return t[r];
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
const require$1 = createRequire$1(import.meta.url);
|
|
520
|
+
async function discoverAndRegisterActions(options) {
|
|
521
|
+
const {
|
|
522
|
+
projectRoot,
|
|
523
|
+
actionsDir = "src/actions",
|
|
524
|
+
registry = actionRegistry,
|
|
525
|
+
verbose = false,
|
|
526
|
+
viteServer
|
|
527
|
+
} = options;
|
|
528
|
+
const result = {
|
|
529
|
+
actionCount: 0,
|
|
530
|
+
actionNames: [],
|
|
531
|
+
scannedFiles: []
|
|
532
|
+
};
|
|
533
|
+
const actionsPath = path.resolve(projectRoot, actionsDir);
|
|
534
|
+
if (!fs.existsSync(actionsPath)) {
|
|
535
|
+
if (verbose) {
|
|
536
|
+
console.log(`[Actions] No actions directory found at ${actionsPath}`);
|
|
537
|
+
}
|
|
538
|
+
return result;
|
|
539
|
+
}
|
|
540
|
+
const actionFiles = await findActionFiles(actionsPath);
|
|
541
|
+
if (verbose) {
|
|
542
|
+
console.log(`[Actions] Found ${actionFiles.length} action file(s)`);
|
|
543
|
+
}
|
|
544
|
+
for (const filePath of actionFiles) {
|
|
545
|
+
result.scannedFiles.push(filePath);
|
|
546
|
+
try {
|
|
547
|
+
let module;
|
|
548
|
+
if (viteServer) {
|
|
549
|
+
module = await viteServer.ssrLoadModule(filePath);
|
|
550
|
+
} else {
|
|
551
|
+
module = await import(filePath);
|
|
552
|
+
}
|
|
553
|
+
for (const [exportName, exportValue] of Object.entries(module)) {
|
|
554
|
+
if (isJayAction(exportValue)) {
|
|
555
|
+
registry.register(exportValue);
|
|
556
|
+
result.actionNames.push(exportValue.actionName);
|
|
557
|
+
result.actionCount++;
|
|
558
|
+
if (verbose) {
|
|
559
|
+
console.log(`[Actions] Registered: ${exportValue.actionName}`);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
} catch (error) {
|
|
564
|
+
console.error(`[Actions] Failed to import ${filePath}:`, error);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return result;
|
|
568
|
+
}
|
|
569
|
+
async function findActionFiles(dir) {
|
|
570
|
+
const files = [];
|
|
571
|
+
const entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
572
|
+
for (const entry of entries) {
|
|
573
|
+
const fullPath = path.join(dir, entry.name);
|
|
574
|
+
if (entry.isDirectory()) {
|
|
575
|
+
const subFiles = await findActionFiles(fullPath);
|
|
576
|
+
files.push(...subFiles);
|
|
577
|
+
} else if (entry.isFile() && entry.name.endsWith(".actions.ts")) {
|
|
578
|
+
files.push(fullPath);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
return files;
|
|
582
|
+
}
|
|
583
|
+
async function discoverAllPluginActions(options) {
|
|
584
|
+
const { projectRoot, registry = actionRegistry, verbose = false, viteServer } = options;
|
|
585
|
+
const allActions = [];
|
|
586
|
+
const localPluginsPath = path.join(projectRoot, "src/plugins");
|
|
587
|
+
if (fs.existsSync(localPluginsPath)) {
|
|
588
|
+
const pluginDirs = await fs.promises.readdir(localPluginsPath, { withFileTypes: true });
|
|
589
|
+
for (const entry of pluginDirs) {
|
|
590
|
+
if (entry.isDirectory()) {
|
|
591
|
+
const pluginPath = path.join(localPluginsPath, entry.name);
|
|
592
|
+
const actions = await discoverPluginActions(
|
|
593
|
+
pluginPath,
|
|
594
|
+
projectRoot,
|
|
595
|
+
registry,
|
|
596
|
+
verbose,
|
|
597
|
+
viteServer
|
|
598
|
+
);
|
|
599
|
+
allActions.push(...actions);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
const npmActions = await discoverNpmPluginActions(projectRoot, registry, verbose, viteServer);
|
|
604
|
+
allActions.push(...npmActions);
|
|
605
|
+
return allActions;
|
|
606
|
+
}
|
|
607
|
+
async function discoverNpmPluginActions(projectRoot, registry, verbose, viteServer) {
|
|
608
|
+
const allActions = [];
|
|
609
|
+
const packageJsonPath = path.join(projectRoot, "package.json");
|
|
610
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
611
|
+
return allActions;
|
|
612
|
+
}
|
|
613
|
+
try {
|
|
614
|
+
const packageJson = JSON.parse(await fs.promises.readFile(packageJsonPath, "utf-8"));
|
|
615
|
+
const dependencies = {
|
|
616
|
+
...packageJson.dependencies,
|
|
617
|
+
...packageJson.devDependencies
|
|
618
|
+
};
|
|
619
|
+
for (const packageName of Object.keys(dependencies)) {
|
|
620
|
+
try {
|
|
621
|
+
const pluginYamlPath = tryResolvePluginYaml(packageName, projectRoot);
|
|
622
|
+
if (!pluginYamlPath) {
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
625
|
+
const pluginDir = path.dirname(pluginYamlPath);
|
|
626
|
+
const pluginConfig = loadPluginManifest(pluginDir);
|
|
627
|
+
if (!pluginConfig || !pluginConfig.actions || !Array.isArray(pluginConfig.actions)) {
|
|
628
|
+
continue;
|
|
629
|
+
}
|
|
630
|
+
if (verbose) {
|
|
631
|
+
console.log(
|
|
632
|
+
`[Actions] NPM plugin "${packageName}" declares actions:`,
|
|
633
|
+
pluginConfig.actions
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
const actions = await registerNpmPluginActions(
|
|
637
|
+
packageName,
|
|
638
|
+
pluginConfig,
|
|
639
|
+
registry,
|
|
640
|
+
verbose,
|
|
641
|
+
viteServer
|
|
642
|
+
);
|
|
643
|
+
allActions.push(...actions);
|
|
644
|
+
} catch {
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
} catch (error) {
|
|
649
|
+
console.error("[Actions] Failed to read project package.json:", error);
|
|
650
|
+
}
|
|
651
|
+
return allActions;
|
|
652
|
+
}
|
|
653
|
+
function tryResolvePluginYaml(packageName, projectRoot) {
|
|
654
|
+
try {
|
|
655
|
+
return require$1.resolve(`${packageName}/plugin.yaml`, {
|
|
656
|
+
paths: [projectRoot]
|
|
657
|
+
});
|
|
658
|
+
} catch {
|
|
659
|
+
return null;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
async function registerNpmPluginActions(packageName, pluginConfig, registry, verbose, viteServer) {
|
|
663
|
+
const registeredActions = [];
|
|
664
|
+
try {
|
|
665
|
+
let pluginModule;
|
|
666
|
+
if (viteServer) {
|
|
667
|
+
pluginModule = await viteServer.ssrLoadModule(packageName);
|
|
668
|
+
} else {
|
|
669
|
+
pluginModule = await import(packageName);
|
|
670
|
+
}
|
|
671
|
+
for (const actionName of pluginConfig.actions) {
|
|
672
|
+
const actionExport = pluginModule[actionName];
|
|
673
|
+
if (actionExport && isJayAction(actionExport)) {
|
|
674
|
+
registry.register(actionExport);
|
|
675
|
+
registeredActions.push(actionExport.actionName);
|
|
676
|
+
if (verbose) {
|
|
677
|
+
console.log(
|
|
678
|
+
`[Actions] Registered NPM plugin action: ${actionExport.actionName}`
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
} else {
|
|
682
|
+
console.warn(
|
|
683
|
+
`[Actions] NPM plugin "${packageName}" declares action "${actionName}" but it's not exported or not a JayAction`
|
|
684
|
+
);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
} catch (importError) {
|
|
688
|
+
console.error(`[Actions] Failed to import NPM plugin "${packageName}":`, importError);
|
|
689
|
+
}
|
|
690
|
+
return registeredActions;
|
|
691
|
+
}
|
|
692
|
+
async function discoverPluginActions(pluginPath, projectRoot, registry = actionRegistry, verbose = false, viteServer) {
|
|
693
|
+
const pluginConfig = loadPluginManifest(pluginPath);
|
|
694
|
+
if (!pluginConfig) {
|
|
695
|
+
return [];
|
|
696
|
+
}
|
|
697
|
+
if (!pluginConfig.actions || !Array.isArray(pluginConfig.actions)) {
|
|
698
|
+
return [];
|
|
699
|
+
}
|
|
700
|
+
const registeredActions = [];
|
|
701
|
+
const pluginName = pluginConfig.name || path.basename(pluginPath);
|
|
702
|
+
if (verbose) {
|
|
703
|
+
console.log(`[Actions] Plugin "${pluginName}" declares actions:`, pluginConfig.actions);
|
|
704
|
+
}
|
|
705
|
+
let modulePath = pluginConfig.module ? path.join(pluginPath, pluginConfig.module) : path.join(pluginPath, "index.ts");
|
|
706
|
+
if (!fs.existsSync(modulePath)) {
|
|
707
|
+
const tsPath = modulePath + ".ts";
|
|
708
|
+
const jsPath = modulePath + ".js";
|
|
709
|
+
if (fs.existsSync(tsPath)) {
|
|
710
|
+
modulePath = tsPath;
|
|
711
|
+
} else if (fs.existsSync(jsPath)) {
|
|
712
|
+
modulePath = jsPath;
|
|
713
|
+
} else {
|
|
714
|
+
console.warn(`[Actions] Plugin "${pluginName}" module not found at ${modulePath}`);
|
|
715
|
+
return [];
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
try {
|
|
719
|
+
let pluginModule;
|
|
720
|
+
if (viteServer) {
|
|
721
|
+
pluginModule = await viteServer.ssrLoadModule(modulePath);
|
|
722
|
+
} else {
|
|
723
|
+
pluginModule = await import(modulePath);
|
|
724
|
+
}
|
|
725
|
+
for (const actionName of pluginConfig.actions) {
|
|
726
|
+
const actionExport = pluginModule[actionName];
|
|
727
|
+
if (actionExport && isJayAction(actionExport)) {
|
|
728
|
+
registry.register(actionExport);
|
|
729
|
+
registeredActions.push(actionExport.actionName);
|
|
730
|
+
if (verbose) {
|
|
731
|
+
console.log(
|
|
732
|
+
`[Actions] Registered plugin action: ${actionExport.actionName}`
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
} else {
|
|
736
|
+
console.warn(
|
|
737
|
+
`[Actions] Plugin "${pluginName}" declares action "${actionName}" but it's not exported or not a JayAction`
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
} catch (importError) {
|
|
742
|
+
console.error(`[Actions] Failed to import plugin module at ${modulePath}:`, importError);
|
|
743
|
+
}
|
|
744
|
+
return registeredActions;
|
|
745
|
+
}
|
|
746
|
+
const require2 = createRequire$1(import.meta.url);
|
|
747
|
+
async function discoverPluginsWithInit(options) {
|
|
748
|
+
const { projectRoot, verbose = false } = options;
|
|
749
|
+
const plugins = [];
|
|
750
|
+
const localPluginsPath = path.join(projectRoot, "src/plugins");
|
|
751
|
+
if (fs.existsSync(localPluginsPath)) {
|
|
752
|
+
try {
|
|
753
|
+
const entries = fs.readdirSync(localPluginsPath, { withFileTypes: true });
|
|
754
|
+
for (const entry of entries) {
|
|
755
|
+
if (!entry.isDirectory())
|
|
756
|
+
continue;
|
|
757
|
+
const pluginPath = path.join(localPluginsPath, entry.name);
|
|
758
|
+
const manifest = loadPluginManifest(pluginPath);
|
|
759
|
+
if (!manifest)
|
|
760
|
+
continue;
|
|
761
|
+
const initConfig = resolvePluginInit(pluginPath, manifest.init, true);
|
|
762
|
+
if (!initConfig)
|
|
763
|
+
continue;
|
|
764
|
+
const dependencies = await getPackageDependencies(pluginPath);
|
|
765
|
+
plugins.push({
|
|
766
|
+
name: manifest.name || entry.name,
|
|
767
|
+
pluginPath,
|
|
768
|
+
packageName: pluginPath,
|
|
769
|
+
// For local, use path
|
|
770
|
+
isLocal: true,
|
|
771
|
+
initModule: initConfig.module,
|
|
772
|
+
initExport: initConfig.export,
|
|
773
|
+
dependencies
|
|
774
|
+
});
|
|
775
|
+
if (verbose) {
|
|
776
|
+
console.log(
|
|
777
|
+
`[PluginInit] Found local plugin with init: ${manifest.name || entry.name}`
|
|
778
|
+
);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
} catch (error) {
|
|
782
|
+
console.warn(`[PluginInit] Failed to scan local plugins: ${error}`);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
const projectPackageJsonPath = path.join(projectRoot, "package.json");
|
|
786
|
+
if (fs.existsSync(projectPackageJsonPath)) {
|
|
787
|
+
try {
|
|
788
|
+
const projectPackageJson = JSON.parse(fs.readFileSync(projectPackageJsonPath, "utf-8"));
|
|
789
|
+
const allDeps = {
|
|
790
|
+
...projectPackageJson.dependencies,
|
|
791
|
+
...projectPackageJson.devDependencies
|
|
792
|
+
};
|
|
793
|
+
for (const depName of Object.keys(allDeps)) {
|
|
794
|
+
let pluginYamlPath;
|
|
795
|
+
try {
|
|
796
|
+
pluginYamlPath = require2.resolve(`${depName}/plugin.yaml`, {
|
|
797
|
+
paths: [projectRoot]
|
|
798
|
+
});
|
|
799
|
+
} catch {
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
const pluginPath = path.dirname(pluginYamlPath);
|
|
803
|
+
const manifest = loadPluginManifest(pluginPath);
|
|
804
|
+
if (!manifest)
|
|
805
|
+
continue;
|
|
806
|
+
const initConfig = resolvePluginInit(pluginPath, manifest.init, false);
|
|
807
|
+
if (!initConfig)
|
|
808
|
+
continue;
|
|
809
|
+
const dependencies = await getPackageDependencies(pluginPath);
|
|
810
|
+
plugins.push({
|
|
811
|
+
name: manifest.name || depName,
|
|
812
|
+
pluginPath,
|
|
813
|
+
packageName: depName,
|
|
814
|
+
isLocal: false,
|
|
815
|
+
initModule: initConfig.module,
|
|
816
|
+
initExport: initConfig.export,
|
|
817
|
+
dependencies
|
|
818
|
+
});
|
|
819
|
+
if (verbose) {
|
|
820
|
+
console.log(`[PluginInit] Found NPM plugin with init: ${depName}`);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
} catch (error) {
|
|
824
|
+
console.warn(`[PluginInit] Failed to scan NPM plugins: ${error}`);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
return plugins;
|
|
828
|
+
}
|
|
829
|
+
function resolvePluginInit(pluginPath, initConfig, isLocal) {
|
|
830
|
+
const defaultExport = "init";
|
|
831
|
+
if (isLocal) {
|
|
832
|
+
const initPaths = [
|
|
833
|
+
path.join(pluginPath, "lib/init.ts"),
|
|
834
|
+
path.join(pluginPath, "lib/init.js"),
|
|
835
|
+
path.join(pluginPath, "init.ts"),
|
|
836
|
+
path.join(pluginPath, "init.js")
|
|
837
|
+
];
|
|
838
|
+
for (const initPath of initPaths) {
|
|
839
|
+
if (fs.existsSync(initPath)) {
|
|
840
|
+
const relativePath = path.relative(pluginPath, initPath);
|
|
841
|
+
const modulePath = relativePath.replace(/\.(ts|js)$/, "");
|
|
842
|
+
const exportName = typeof initConfig === "string" ? initConfig : defaultExport;
|
|
843
|
+
return { module: modulePath, export: exportName };
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
return null;
|
|
847
|
+
}
|
|
848
|
+
const packageJsonPath = path.join(pluginPath, "package.json");
|
|
849
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
850
|
+
return null;
|
|
851
|
+
}
|
|
852
|
+
try {
|
|
853
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
854
|
+
const hasMain = packageJson.main || packageJson.exports;
|
|
855
|
+
if (!hasMain && !initConfig) {
|
|
856
|
+
return null;
|
|
857
|
+
}
|
|
858
|
+
const exportName = typeof initConfig === "string" ? initConfig : defaultExport;
|
|
859
|
+
return { module: "", export: exportName };
|
|
860
|
+
} catch {
|
|
861
|
+
return null;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
async function getPackageDependencies(pluginPath) {
|
|
865
|
+
const packageJsonPath = path.join(pluginPath, "package.json");
|
|
866
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
867
|
+
return [];
|
|
868
|
+
}
|
|
869
|
+
try {
|
|
870
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
871
|
+
return Object.keys(packageJson.dependencies || {});
|
|
872
|
+
} catch {
|
|
873
|
+
return [];
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
function sortPluginsByDependencies(plugins) {
|
|
877
|
+
const pluginNames = new Set(plugins.map((p) => p.packageName));
|
|
878
|
+
const sorted = [];
|
|
879
|
+
const visited = /* @__PURE__ */ new Set();
|
|
880
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
881
|
+
function visit(plugin) {
|
|
882
|
+
if (visited.has(plugin.packageName))
|
|
883
|
+
return;
|
|
884
|
+
if (visiting.has(plugin.packageName)) {
|
|
885
|
+
console.warn(`[PluginInit] Circular dependency detected for ${plugin.name}`);
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
visiting.add(plugin.packageName);
|
|
889
|
+
for (const dep of plugin.dependencies) {
|
|
890
|
+
if (pluginNames.has(dep)) {
|
|
891
|
+
const depPlugin = plugins.find((p) => p.packageName === dep);
|
|
892
|
+
if (depPlugin) {
|
|
893
|
+
visit(depPlugin);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
visiting.delete(plugin.packageName);
|
|
898
|
+
visited.add(plugin.packageName);
|
|
899
|
+
sorted.push(plugin);
|
|
900
|
+
}
|
|
901
|
+
for (const plugin of plugins) {
|
|
902
|
+
visit(plugin);
|
|
903
|
+
}
|
|
904
|
+
return sorted;
|
|
905
|
+
}
|
|
906
|
+
async function executePluginServerInits(plugins, viteServer, verbose = false) {
|
|
907
|
+
for (const plugin of plugins) {
|
|
908
|
+
try {
|
|
909
|
+
let modulePath;
|
|
910
|
+
if (plugin.isLocal) {
|
|
911
|
+
modulePath = path.join(plugin.pluginPath, plugin.initModule);
|
|
912
|
+
} else if (plugin.initModule) {
|
|
913
|
+
modulePath = `${plugin.packageName}/${plugin.initModule}`;
|
|
914
|
+
} else {
|
|
915
|
+
modulePath = plugin.packageName;
|
|
916
|
+
}
|
|
917
|
+
let pluginModule;
|
|
918
|
+
if (viteServer) {
|
|
919
|
+
pluginModule = await viteServer.ssrLoadModule(modulePath);
|
|
920
|
+
} else {
|
|
921
|
+
pluginModule = await import(modulePath);
|
|
922
|
+
}
|
|
923
|
+
const jayInit = pluginModule[plugin.initExport];
|
|
924
|
+
if (!jayInit || jayInit.__brand !== "JayInit") {
|
|
925
|
+
console.warn(
|
|
926
|
+
`[PluginInit] Plugin "${plugin.name}" init module doesn't export a valid JayInit at "${plugin.initExport}"`
|
|
927
|
+
);
|
|
928
|
+
continue;
|
|
929
|
+
}
|
|
930
|
+
if (typeof jayInit._serverInit === "function") {
|
|
931
|
+
if (verbose) {
|
|
932
|
+
console.log(`[DevServer] Running server init: ${plugin.name}`);
|
|
933
|
+
}
|
|
934
|
+
const clientData = await jayInit._serverInit();
|
|
935
|
+
if (clientData !== void 0 && clientData !== null) {
|
|
936
|
+
setClientInitData(plugin.name, clientData);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
} catch (error) {
|
|
940
|
+
console.error(
|
|
941
|
+
`[PluginInit] Failed to execute server init for "${plugin.name}":`,
|
|
942
|
+
error
|
|
943
|
+
);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
function preparePluginClientInits(plugins) {
|
|
948
|
+
return plugins.map((plugin) => {
|
|
949
|
+
let importPath;
|
|
950
|
+
if (plugin.isLocal) {
|
|
951
|
+
importPath = path.join(plugin.pluginPath, plugin.initModule);
|
|
952
|
+
} else if (plugin.initModule) {
|
|
953
|
+
importPath = `${plugin.packageName}/${plugin.initModule}`;
|
|
954
|
+
} else {
|
|
955
|
+
importPath = `${plugin.packageName}/client`;
|
|
956
|
+
}
|
|
957
|
+
return {
|
|
958
|
+
name: plugin.name,
|
|
959
|
+
importPath,
|
|
960
|
+
initExport: plugin.initExport
|
|
961
|
+
};
|
|
212
962
|
});
|
|
213
963
|
}
|
|
214
964
|
export {
|
|
965
|
+
ActionRegistry,
|
|
215
966
|
DevSlowlyChangingPhase,
|
|
967
|
+
actionRegistry,
|
|
968
|
+
clearActionRegistry,
|
|
969
|
+
clearClientInitData,
|
|
216
970
|
clearLifecycleCallbacks,
|
|
217
971
|
clearServiceRegistry,
|
|
972
|
+
discoverAllPluginActions,
|
|
973
|
+
discoverAndRegisterActions,
|
|
974
|
+
discoverPluginActions,
|
|
975
|
+
discoverPluginsWithInit,
|
|
976
|
+
executeAction,
|
|
977
|
+
executePluginServerInits,
|
|
218
978
|
generateClientScript,
|
|
979
|
+
getActionCacheHeaders,
|
|
980
|
+
getClientInitData,
|
|
981
|
+
getClientInitDataForKey,
|
|
982
|
+
getRegisteredAction,
|
|
983
|
+
getRegisteredActionNames,
|
|
219
984
|
getService,
|
|
985
|
+
hasAction,
|
|
220
986
|
hasService,
|
|
221
987
|
loadPageParts,
|
|
222
988
|
onInit,
|
|
223
989
|
onShutdown,
|
|
990
|
+
preparePluginClientInits,
|
|
991
|
+
registerAction,
|
|
224
992
|
registerService,
|
|
225
993
|
renderFastChangingData,
|
|
226
994
|
resolveServices,
|
|
227
995
|
runInitCallbacks,
|
|
228
996
|
runLoadParams,
|
|
229
997
|
runShutdownCallbacks,
|
|
230
|
-
runSlowlyChangingRender
|
|
998
|
+
runSlowlyChangingRender,
|
|
999
|
+
setClientInitData,
|
|
1000
|
+
sortPluginsByDependencies
|
|
231
1001
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/stack-server-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.mts",
|
|
@@ -26,16 +26,18 @@
|
|
|
26
26
|
"test:watch": "vitest"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@jay-framework/compiler-jay-html": "^0.
|
|
30
|
-
"@jay-framework/
|
|
31
|
-
"@jay-framework/
|
|
32
|
-
"@jay-framework/
|
|
33
|
-
"@jay-framework/
|
|
29
|
+
"@jay-framework/compiler-jay-html": "^0.10.0",
|
|
30
|
+
"@jay-framework/compiler-shared": "^0.10.0",
|
|
31
|
+
"@jay-framework/component": "^0.10.0",
|
|
32
|
+
"@jay-framework/fullstack-component": "^0.10.0",
|
|
33
|
+
"@jay-framework/runtime": "^0.10.0",
|
|
34
|
+
"@jay-framework/stack-route-scanner": "^0.10.0",
|
|
35
|
+
"@jay-framework/view-state-merge": "^0.10.0"
|
|
34
36
|
},
|
|
35
37
|
"devDependencies": {
|
|
36
|
-
"@jay-framework/dev-environment": "^0.
|
|
37
|
-
"@jay-framework/jay-cli": "^0.
|
|
38
|
-
"@jay-framework/stack-client-runtime": "^0.
|
|
38
|
+
"@jay-framework/dev-environment": "^0.10.0",
|
|
39
|
+
"@jay-framework/jay-cli": "^0.10.0",
|
|
40
|
+
"@jay-framework/stack-client-runtime": "^0.10.0",
|
|
39
41
|
"@types/express": "^5.0.2",
|
|
40
42
|
"@types/node": "^22.15.21",
|
|
41
43
|
"nodemon": "^3.0.3",
|