@azure-net/kit 5.0.4 → 5.1.1

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.
@@ -193,7 +193,13 @@ const withTimeout = (signal, timeout) => {
193
193
  };
194
194
  };
195
195
  const shouldRetryError = (error) => {
196
- return error instanceof HttpServiceError && error.type === HttpErrorTypes.External;
196
+ if (error instanceof Error && error.name === 'AbortError')
197
+ return false;
198
+ if (error instanceof TypeError)
199
+ return true;
200
+ if (!(error instanceof HttpServiceError) || error.type !== HttpErrorTypes.External)
201
+ return false;
202
+ return error.status === 408 || error.status === 425 || error.status === 429 || error.status >= 500;
197
203
  };
198
204
  const normalizeUnknownError = (error) => {
199
205
  if (error instanceof Error)
@@ -202,14 +208,16 @@ const normalizeUnknownError = (error) => {
202
208
  };
203
209
  const parseResponse = async (response, request) => {
204
210
  const raw = request.includeRaw && typeof response?.clone === 'function' ? response?.clone() : undefined;
205
- let data;
211
+ const hasNoBody = request.method === HttpInstanceFetchMethods.HEAD || response.status === 204 || response.status === 205;
212
+ let data = undefined;
206
213
  let parseError;
207
- try {
208
- data = await parseBodyByFormat(response, request.responseFormat);
209
- }
210
- catch (error) {
211
- parseError = normalizeUnknownError(error);
212
- data = undefined;
214
+ if (!hasNoBody) {
215
+ try {
216
+ data = await parseBodyByFormat(response, request.responseFormat);
217
+ }
218
+ catch (error) {
219
+ parseError = normalizeUnknownError(error);
220
+ }
213
221
  }
214
222
  if (!response.ok || parseError) {
215
223
  const message = !response.ok
@@ -1,7 +1,5 @@
1
1
  import type { Plugin } from 'vite';
2
2
  export interface AzureNetPluginOptions {
3
3
  silentChromeDevtools?: boolean;
4
- syncFromServer?: boolean;
5
- syncTransformMode?: 'ast' | 'regex' | 'hybrid';
6
4
  }
7
5
  export declare const AzureNetPlugin: (options?: AzureNetPluginOptions) => Plugin;
@@ -1,10 +1,7 @@
1
1
  import path from 'node:path';
2
2
  import fs from 'node:fs';
3
- import ts from 'typescript';
4
3
  const VIRTUAL_SERVER_UTILS_ID = 'virtual:azure-net-kit/server-utils';
5
- const VIRTUAL_UNIVERSAL_UTILS_ID = 'virtual:azure-net-kit/universal-utils';
6
4
  const RESOLVED_VIRTUAL_SERVER_UTILS_ID = `\0${VIRTUAL_SERVER_UTILS_ID}`;
7
- const RESOLVED_VIRTUAL_UNIVERSAL_UTILS_ID = `\0${VIRTUAL_UNIVERSAL_UTILS_ID}`;
8
5
  const VIRTUAL_SERVER_HOOKS_ID = 'virtual:azure-net-kit/hooks.server';
9
6
  const VIRTUAL_CLIENT_HOOKS_ID = 'virtual:azure-net-kit/hooks.client';
10
7
  const RESOLVED_VIRTUAL_SERVER_HOOKS_ID = `\0${VIRTUAL_SERVER_HOOKS_ID}`;
@@ -12,33 +9,6 @@ const RESOLVED_VIRTUAL_CLIENT_HOOKS_ID = `\0${VIRTUAL_CLIENT_HOOKS_ID}`;
12
9
  const VIRTUAL_PROGRAM_ID = 'virtual:azure-net-kit/program';
13
10
  const RESOLVED_VIRTUAL_PROGRAM_ID = `\0${VIRTUAL_PROGRAM_ID}`;
14
11
  const GENERATED_MARKER = '__AZURE_NET_KIT_VIRTUAL_HOOK__';
15
- const SYNC_MARKER = "void '__EDGES_SYNC_WRAPPED__';";
16
- const LOAD_EXPORT_PATTERN = /export\s+const\s+load\s*(?::\s*[^=]+)?=/;
17
- const ACTIONS_EXPORT_PATTERN = /export\s+const\s+actions\s*(?::\s*[^=]+)?=/;
18
- const SERVER_ROUTE_PATTERN = /[\\/]\+((page|layout)\.server)\.(t|j)s$/;
19
- const UNIVERSAL_ROUTE_PATTERN = /[\\/]\+((page|layout))\.(t|j)s$/;
20
- const AST_SERVER_LOAD_ALIAS = '__edgesWrappedServerLoad';
21
- const AST_ACTIONS_ALIAS = '__edgesWrappedActions';
22
- const AST_UNIVERSAL_LOAD_ALIAS = '__edgesWrappedUniversalLoad';
23
- const applyEdits = (sourceCode, edits) => {
24
- if (edits.length === 0)
25
- return sourceCode;
26
- const sorted = edits.sort((a, b) => b.start - a.start);
27
- let result = sourceCode;
28
- for (const edit of sorted) {
29
- result = result.slice(0, edit.start) + edit.text + result.slice(edit.end);
30
- }
31
- return result;
32
- };
33
- const findImportInsertPosition = (sourceCode) => {
34
- const importRegex = /(?:^|\n)((?:import|export)\s+(?:type\s+)?(?:\{[^}]*\}|\*|\w+)(?:\s+from)?\s+['"][^'"]+['"];?)/gm;
35
- let lastMatch = null;
36
- let match;
37
- while ((match = importRegex.exec(sourceCode)) !== null) {
38
- lastMatch = match;
39
- }
40
- return lastMatch ? lastMatch.index + lastMatch[0].length : 0;
41
- };
42
12
  const findStaticImportInsertPosition = (sourceCode) => {
43
13
  const importRegex = /(?:^|\n)(import\s+(?:type\s+)?(?:\{[^}]*\}|\*|\w+)(?:\s+from)?\s+['"][^'"]+['"];?)/gm;
44
14
  let lastMatch = null;
@@ -48,145 +18,15 @@ const findStaticImportInsertPosition = (sourceCode) => {
48
18
  }
49
19
  return lastMatch ? lastMatch.index + lastMatch[0].length : 0;
50
20
  };
51
- const ensureSyncImport = (sourceCode, importLine) => {
52
- if (sourceCode.includes('__EDGES_SYNC_WRAPPED__'))
53
- return sourceCode;
54
- const insertPos = findImportInsertPosition(sourceCode);
55
- const beforeImports = sourceCode.slice(0, insertPos);
56
- const afterImports = sourceCode.slice(insertPos);
57
- return `${beforeImports}\n${SYNC_MARKER}\n${importLine}\n${afterImports}`;
58
- };
59
- const ensureAstServerImport = (sourceCode) => ensureSyncImport(sourceCode, `import { __withEdgesServerLoad as ${AST_SERVER_LOAD_ALIAS}, __withEdgesActions as ${AST_ACTIONS_ALIAS} } from '${VIRTUAL_SERVER_UTILS_ID}';`);
60
- const ensureAstUniversalImport = (sourceCode) => ensureSyncImport(sourceCode, `import { __withEdgesUniversalLoad as ${AST_UNIVERSAL_LOAD_ALIAS} } from '${VIRTUAL_UNIVERSAL_UTILS_ID}';`);
61
- const ensureRegexServerImport = (sourceCode) => ensureSyncImport(sourceCode, `import { __withEdgesServerLoad, __withEdgesActions } from '${VIRTUAL_SERVER_UTILS_ID}';`);
62
- const ensureRegexUniversalImport = (sourceCode) => ensureSyncImport(sourceCode, `import { __withEdgesUniversalLoad } from '${VIRTUAL_UNIVERSAL_UTILS_ID}';`);
63
- const findExportedLocal = (sourceFile, code, exportedName) => {
64
- const edits = [];
65
- let localName = null;
66
- let found = false;
67
- for (const stmt of sourceFile.statements) {
68
- if (ts.isVariableStatement(stmt)) {
69
- const exportModifier = stmt.modifiers?.find((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword);
70
- if (!exportModifier)
71
- continue;
72
- for (const declaration of stmt.declarationList.declarations) {
73
- if (!ts.isIdentifier(declaration.name) || declaration.name.text !== exportedName)
74
- continue;
75
- localName = declaration.name.text;
76
- found = true;
77
- const modifierStart = exportModifier.getStart(sourceFile);
78
- let modifierEnd = exportModifier.end;
79
- while (modifierEnd < code.length && /\s/.test(code[modifierEnd]))
80
- modifierEnd += 1;
81
- edits.push({ start: modifierStart, end: modifierEnd, text: '' });
82
- break;
83
- }
84
- }
85
- if (!ts.isExportDeclaration(stmt) || !stmt.exportClause || !ts.isNamedExports(stmt.exportClause) || stmt.moduleSpecifier)
86
- continue;
87
- const keepSpecs = [];
88
- let statementHasTarget = false;
89
- for (const element of stmt.exportClause.elements) {
90
- const exportName = element.name.text;
91
- const sourceName = element.propertyName?.text ?? element.name.text;
92
- if (exportName === exportedName) {
93
- statementHasTarget = true;
94
- found = true;
95
- localName = sourceName;
96
- continue;
97
- }
98
- keepSpecs.push(code.slice(element.getStart(sourceFile), element.end).trim());
99
- }
100
- if (!statementHasTarget)
101
- continue;
102
- if (keepSpecs.length === 0) {
103
- edits.push({ start: stmt.getStart(sourceFile), end: stmt.end, text: '' });
104
- }
105
- else {
106
- edits.push({ start: stmt.getStart(sourceFile), end: stmt.end, text: `export { ${keepSpecs.join(', ')} };` });
107
- }
108
- }
109
- return { localName, edits, found };
110
- };
111
- const wrapServerRouteModuleRegex = (sourceCode) => {
112
- if (!LOAD_EXPORT_PATTERN.test(sourceCode) && !ACTIONS_EXPORT_PATTERN.test(sourceCode))
113
- return null;
114
- let wrapped = ensureRegexServerImport(sourceCode);
115
- if (LOAD_EXPORT_PATTERN.test(wrapped)) {
116
- wrapped = wrapped
117
- .replace(LOAD_EXPORT_PATTERN, (match) => match.replace('export const load', 'const __userLoad'))
118
- .concat('\n\nexport const load = __withEdgesServerLoad(__userLoad);');
119
- }
120
- if (ACTIONS_EXPORT_PATTERN.test(wrapped)) {
121
- wrapped = wrapped
122
- .replace(ACTIONS_EXPORT_PATTERN, (match) => match.replace('export const actions', 'const __userActions'))
123
- .concat('\n\nexport const actions = __withEdgesActions(__userActions);');
124
- }
125
- return wrapped;
126
- };
127
- const wrapUniversalRouteModuleRegex = (sourceCode) => {
128
- if (!LOAD_EXPORT_PATTERN.test(sourceCode))
129
- return null;
130
- return ensureRegexUniversalImport(sourceCode)
131
- .replace(LOAD_EXPORT_PATTERN, (match) => match.replace('export const load', 'const __userUniversalLoad'))
132
- .concat('\n\nexport const load = __withEdgesUniversalLoad(__userUniversalLoad);');
133
- };
134
- const wrapServerRouteModuleAst = (sourceCode) => {
135
- if (sourceCode.includes('__EDGES_SYNC_WRAPPED__'))
136
- return null;
137
- let sourceFile;
138
- try {
139
- sourceFile = ts.createSourceFile('route.ts', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
140
- }
141
- catch {
142
- return null;
143
- }
144
- const loadInfo = findExportedLocal(sourceFile, sourceCode, 'load');
145
- const actionsInfo = findExportedLocal(sourceFile, sourceCode, 'actions');
146
- if (!loadInfo.found && !actionsInfo.found)
147
- return null;
148
- if ((loadInfo.found && !loadInfo.localName) || (actionsInfo.found && !actionsInfo.localName))
149
- return null;
150
- let nextCode = applyEdits(sourceCode, [...loadInfo.edits, ...actionsInfo.edits]);
151
- nextCode = ensureAstServerImport(nextCode);
152
- const append = [];
153
- if (loadInfo.localName) {
154
- append.push(`const __edgesServerLoad = ${AST_SERVER_LOAD_ALIAS}(${loadInfo.localName});`);
155
- append.push('export { __edgesServerLoad as load };');
156
- }
157
- if (actionsInfo.localName) {
158
- append.push(`const __edgesServerActions = ${AST_ACTIONS_ALIAS}(${actionsInfo.localName});`);
159
- append.push('export { __edgesServerActions as actions };');
160
- }
161
- return `${nextCode}\n\n${append.join('\n')}`;
162
- };
163
- const wrapUniversalRouteModuleAst = (sourceCode) => {
164
- if (sourceCode.includes('__EDGES_SYNC_WRAPPED__'))
165
- return null;
166
- let sourceFile;
167
- try {
168
- sourceFile = ts.createSourceFile('route.ts', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
169
- }
170
- catch {
171
- return null;
172
- }
173
- const loadInfo = findExportedLocal(sourceFile, sourceCode, 'load');
174
- if (!loadInfo.found || !loadInfo.localName)
175
- return null;
176
- let nextCode = applyEdits(sourceCode, [...loadInfo.edits]);
177
- nextCode = ensureAstUniversalImport(nextCode);
178
- return `${nextCode}\n\nconst __edgesUniversalLoad = ${AST_UNIVERSAL_LOAD_ALIAS}(${loadInfo.localName});\nexport { __edgesUniversalLoad as load };`;
179
- };
180
21
  const createVirtualServerHooks = (silentChromeDevtools) => `// ${GENERATED_MARKER}
181
22
  import { edgesHandle, edgesHandleRaw } from '${VIRTUAL_SERVER_UTILS_ID}';
182
23
 
183
24
  const getRegister = async () => (await import('${VIRTUAL_PROGRAM_ID}')).register;
184
25
 
185
- export const init = () => undefined;
26
+ export const init = async () => (await getRegister()).serverInit();
186
27
 
187
28
  export const handle = edgesHandle(async ({ serialize, edgesEvent, resolve }) => {
188
29
  const register = await getRegister();
189
- await register.serverInit?.();
190
30
 
191
31
  return register.handle({
192
32
  event: edgesEvent,
@@ -203,48 +43,19 @@ export const handle = edgesHandle(async ({ serialize, edgesEvent, resolve }) =>
203
43
  ${silentChromeDevtools ? ')' : ', false)'};
204
44
 
205
45
  export const handleError = async ({ error, event, status, message }) => {
206
- const register = await edgesHandleRaw(event, async () => await getRegister());
207
-
208
- return register.serverError({ error, event, status, message });
209
- };
210
- `;
211
- const createVirtualServerUtils = () => "export { edgesHandle, edgesHandleRaw, __autoWrapHandle, __withEdgesServerLoad, __withEdgesActions } from '@azure-net/kit/edges/internal-package/utils';";
212
- const createVirtualUniversalUtils = () => `const EDGES_STATE_FIELD = '__edges_state__';
213
- const EDGES_REV_FIELD = '__edges_rev__';
214
-
215
- const isObjectRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
216
-
217
- export const __withEdgesUniversalLoad = (load) => {
218
- \tconst wrapped = async (...args) => {
219
- \t\tconst event = args[0];
220
- \t\tconst result = await load(...args);
221
- \t\tif (!isObjectRecord(event?.data)) return result;
222
-
223
- \t\tconst inheritedState = event.data[EDGES_STATE_FIELD];
224
- \t\tconst inheritedRev = event.data[EDGES_REV_FIELD];
225
- \t\tif (!inheritedState) return result;
46
+ let result;
226
47
 
227
- \t\tif (isObjectRecord(result)) {
228
- \t\t\treturn {
229
- \t\t\t\t...result,
230
- \t\t\t\t[EDGES_STATE_FIELD]: inheritedState,
231
- \t\t\t\t[EDGES_REV_FIELD]: inheritedRev
232
- \t\t\t};
233
- \t\t}
48
+ await edgesHandleRaw(event, async () => {
49
+ const register = await getRegister();
50
+ result = await register.serverError({ error, event, status, message });
234
51
 
235
- \t\tif (result === undefined) {
236
- \t\t\treturn {
237
- \t\t\t\t[EDGES_STATE_FIELD]: inheritedState,
238
- \t\t\t\t[EDGES_REV_FIELD]: inheritedRev
239
- \t\t\t};
240
- \t\t}
241
-
242
- \t\treturn result;
243
- \t};
52
+ return new Response(null, { status: 204 });
53
+ });
244
54
 
245
- \treturn wrapped;
55
+ return result;
246
56
  };
247
57
  `;
58
+ const createVirtualServerUtils = () => "export { edgesHandle, edgesHandleRaw } from '@azure-net/kit/edges/internal-package/utils';";
248
59
  const createVirtualClientHooks = () => `// ${GENERATED_MARKER}
249
60
  const getRegister = async () => (await import('${VIRTUAL_PROGRAM_ID}')).register;
250
61
 
@@ -258,10 +69,14 @@ const createVirtualProgram = (root) => {
258
69
  return `export { register } from '/src/program.ts';`;
259
70
  if (fs.existsSync(jsProgram))
260
71
  return `export { register } from '/src/program.js';`;
261
- return `import { createApp } from '@azure-net/kit';
262
-
263
- export const { register, Container } = createApp((app) => app);
264
- `;
72
+ throw new Error('[AzureNetPlugin] src/program.ts is required. Create it and export register from createApp().');
73
+ };
74
+ const assertProgramExists = (root) => {
75
+ const tsProgram = path.join(root, 'src', 'program.ts');
76
+ const jsProgram = path.join(root, 'src', 'program.js');
77
+ if (fs.existsSync(tsProgram) || fs.existsSync(jsProgram))
78
+ return;
79
+ throw new Error('[AzureNetPlugin] src/program.ts is required. Create it and export register from createApp().');
265
80
  };
266
81
  const hasUserHook = (root, hookName) => {
267
82
  const srcPath = path.join(root, 'src');
@@ -290,6 +105,13 @@ const ensureVirtualImport = (sourceCode, importLine) => {
290
105
  const transformGeneratedServerInternal = (sourceCode) => {
291
106
  if (sourceCode.includes(GENERATED_MARKER))
292
107
  return null;
108
+ if (/hooks\.server\.(?:ts|js)/.test(sourceCode)) {
109
+ throw new Error('[AzureNetPlugin] SvelteKit detected a user-managed hooks.server file. Move its lifecycle code to src/program.ts via createApp().');
110
+ }
111
+ const getHooksPattern = /export\s+async\s+function\s+get_hooks\s*\(\)\s*\{[\s\S]*?\n\}/m;
112
+ if (!getHooksPattern.test(sourceCode)) {
113
+ throw new Error('[AzureNetPlugin] Unsupported SvelteKit generated server internals: get_hooks() was not found.');
114
+ }
293
115
  const universalImportMatch = sourceCode.match(/\(\{\s*reroute,\s*transport\s*\}\s*=\s*await\s*import\([^)]+\)\);/);
294
116
  const universalImport = universalImportMatch?.[0] ? `\n\t${universalImportMatch[0]}` : '';
295
117
  const importLine = `import * as __azureNetServerHooks from '${VIRTUAL_SERVER_HOOKS_ID}';`;
@@ -307,15 +129,21 @@ const transformGeneratedServerInternal = (sourceCode) => {
307
129
  \t\ttransport
308
130
  \t};
309
131
  }`;
310
- const transformed = ensureVirtualImport(sourceCode, `// ${GENERATED_MARKER}\n${importLine}`).replace(/export\s+async\s+function\s+get_hooks\s*\(\)\s*\{[\s\S]*?\n\}/m, getHooksReplacement);
132
+ const transformed = ensureVirtualImport(sourceCode, `// ${GENERATED_MARKER}\n${importLine}`).replace(getHooksPattern, getHooksReplacement);
311
133
  return transformed;
312
134
  };
313
135
  const transformGeneratedClientApp = (sourceCode) => {
314
136
  if (sourceCode.includes(GENERATED_MARKER))
315
137
  return null;
138
+ if (/hooks\.client\.(?:ts|js)/.test(sourceCode)) {
139
+ throw new Error('[AzureNetPlugin] SvelteKit detected a user-managed hooks.client file. Move its lifecycle code to src/program.ts via createApp().');
140
+ }
141
+ const handleErrorPattern = /handleError:\s*\(\(\{\s*error\s*\}\)\s*=>\s*\{\s*console\.error\(error\)\s*\}\)/m;
142
+ if (!handleErrorPattern.test(sourceCode)) {
143
+ throw new Error('[AzureNetPlugin] Unsupported SvelteKit generated client app: default handleError was not found.');
144
+ }
316
145
  let transformed = ensureVirtualImport(sourceCode, `// ${GENERATED_MARKER}\nimport * as __azureNetClientHooks from '${VIRTUAL_CLIENT_HOOKS_ID}';`);
317
- transformed = transformed.replace(/import\s+\*\s+as\s+client_hooks\s+from\s+['"][^'"]*hooks\.client\.(?:ts|js)['"];\s*\n*/g, '');
318
- transformed = transformed.replace(/handleError:\s*(?:client_hooks\.handleError\s*\|\|\s*)?\(\(\{\s*error\s*\}\)\s*=>\s*\{\s*console\.error\(error\)\s*\}\)/m, 'handleError: __azureNetClientHooks.handleError');
146
+ transformed = transformed.replace(handleErrorPattern, 'handleError: __azureNetClientHooks.handleError');
319
147
  if (/^\s*init:\s*[^,\n]+,?/m.test(transformed)) {
320
148
  transformed = transformed.replace(/^\s*init:\s*[^,\n]+,?/m, '\tinit: __azureNetClientHooks.init,');
321
149
  }
@@ -325,30 +153,28 @@ const transformGeneratedClientApp = (sourceCode) => {
325
153
  return transformed;
326
154
  };
327
155
  export const AzureNetPlugin = (options) => {
328
- const { silentChromeDevtools = true, syncFromServer = true, syncTransformMode = 'hybrid' } = options || {};
156
+ const { silentChromeDevtools = true } = options ?? {};
329
157
  let root = process.cwd();
330
- let isTestMode = false;
331
158
  return {
332
159
  name: 'azure-net-kit-plugin',
333
160
  enforce: 'pre',
334
- config(config, env) {
161
+ config(config) {
335
162
  root = path.resolve(config.root ?? process.cwd());
336
- isTestMode = env.mode === 'test';
337
163
  assertNoUserHooks(root);
164
+ assertProgramExists(root);
338
165
  },
339
166
  configResolved(config) {
340
167
  root = config.root;
341
- isTestMode ||= config.mode === 'test';
342
168
  assertNoUserHooks(root);
169
+ assertProgramExists(root);
343
170
  },
344
171
  buildStart() {
345
172
  assertNoUserHooks(root);
173
+ assertProgramExists(root);
346
174
  },
347
175
  resolveId(id) {
348
176
  if (id === VIRTUAL_SERVER_UTILS_ID)
349
177
  return RESOLVED_VIRTUAL_SERVER_UTILS_ID;
350
- if (id === VIRTUAL_UNIVERSAL_UTILS_ID)
351
- return RESOLVED_VIRTUAL_UNIVERSAL_UTILS_ID;
352
178
  if (id === VIRTUAL_SERVER_HOOKS_ID)
353
179
  return RESOLVED_VIRTUAL_SERVER_HOOKS_ID;
354
180
  if (id === VIRTUAL_CLIENT_HOOKS_ID)
@@ -360,8 +186,6 @@ export const AzureNetPlugin = (options) => {
360
186
  load(id) {
361
187
  if (id === RESOLVED_VIRTUAL_SERVER_UTILS_ID)
362
188
  return createVirtualServerUtils();
363
- if (id === RESOLVED_VIRTUAL_UNIVERSAL_UTILS_ID)
364
- return createVirtualUniversalUtils();
365
189
  if (id === RESOLVED_VIRTUAL_SERVER_HOOKS_ID)
366
190
  return createVirtualServerHooks(silentChromeDevtools);
367
191
  if (id === RESOLVED_VIRTUAL_CLIENT_HOOKS_ID)
@@ -371,39 +195,14 @@ export const AzureNetPlugin = (options) => {
371
195
  return null;
372
196
  },
373
197
  transform(code, id) {
374
- const normalizedId = id.split(path.sep).join('/');
375
- if (!isTestMode && normalizedId.endsWith('/.svelte-kit/generated/server/internal.js')) {
198
+ const normalizedId = id.split('?')[0].split(path.sep).join('/');
199
+ if (normalizedId.endsWith('/.svelte-kit/generated/server/internal.js')) {
376
200
  const transformed = transformGeneratedServerInternal(code);
377
- if (transformed)
378
- return { code: transformed, map: null };
379
- return null;
201
+ return transformed ? { code: transformed, map: null } : null;
380
202
  }
381
- if (!isTestMode &&
382
- (normalizedId.endsWith('/.svelte-kit/generated/client/app.js') || normalizedId.endsWith('/.svelte-kit/generated/client-optimized/app.js'))) {
203
+ if (normalizedId.endsWith('/.svelte-kit/generated/client/app.js') || normalizedId.endsWith('/.svelte-kit/generated/client-optimized/app.js')) {
383
204
  const transformed = transformGeneratedClientApp(code);
384
- if (transformed)
385
- return { code: transformed, map: null };
386
- return null;
387
- }
388
- if (code.includes('__EDGES_SYNC_WRAPPED__'))
389
- return null;
390
- if (syncFromServer && SERVER_ROUTE_PATTERN.test(id) && !id.includes('hooks.server')) {
391
- const wrapped = syncTransformMode === 'regex'
392
- ? wrapServerRouteModuleRegex(code)
393
- : syncTransformMode === 'ast'
394
- ? wrapServerRouteModuleAst(code)
395
- : (wrapServerRouteModuleAst(code) ?? wrapServerRouteModuleRegex(code));
396
- if (wrapped)
397
- return { code: wrapped, map: null };
398
- }
399
- if (syncFromServer && UNIVERSAL_ROUTE_PATTERN.test(id) && !id.includes('.server.')) {
400
- const wrapped = syncTransformMode === 'regex'
401
- ? wrapUniversalRouteModuleRegex(code)
402
- : syncTransformMode === 'ast'
403
- ? wrapUniversalRouteModuleAst(code)
404
- : (wrapUniversalRouteModuleAst(code) ?? wrapUniversalRouteModuleRegex(code));
405
- if (wrapped)
406
- return { code: wrapped, map: null };
205
+ return transformed ? { code: transformed, map: null } : null;
407
206
  }
408
207
  return null;
409
208
  }
@@ -38,9 +38,7 @@ export interface AppClientErrorContext<TDependencies extends Record<string, unkn
38
38
  status: number;
39
39
  message: string;
40
40
  }
41
- export interface AppServerInitLifecycleContext<TDependencies extends Record<string, unknown>> {
42
- Container: AppContainer<TDependencies>;
43
- }
41
+ export type AppServerInitLifecycleContext = void;
44
42
  export interface AppServerLifecycleContext<TDependencies extends Record<string, unknown>> {
45
43
  Container: AppContainer<TDependencies>;
46
44
  requestContext: ContextData;
@@ -61,7 +59,7 @@ export type AppUniversalLifecycleCallback<TDependencies extends Record<string, u
61
59
  export type AppClientLifecycleCallback<TDependencies extends Record<string, unknown>> = (context: AppClientLifecycleContext<TDependencies>) => MaybePromise<void>;
62
60
  export type AppClientInitLifecycleCallback<TDependencies extends Record<string, unknown>> = (context: AppClientInitLifecycleContext<TDependencies>) => MaybePromise<void>;
63
61
  export type AppClientErrorCallback<TDependencies extends Record<string, unknown>> = (context: AppClientErrorContext<TDependencies>) => ReturnType<HandleClientError>;
64
- export type AppServerInitLifecycleCallback<TDependencies extends Record<string, unknown>> = (context: AppServerInitLifecycleContext<TDependencies>) => ReturnType<ServerInit>;
62
+ export type AppServerInitLifecycleCallback = ServerInit;
65
63
  export type AppServerLifecycleCallback<TDependencies extends Record<string, unknown>> = (context: AppServerLifecycleContext<TDependencies>) => MaybePromise<Response | void>;
66
64
  export type AppServerErrorCallback<TDependencies extends Record<string, unknown>> = (context: AppServerErrorContext<TDependencies>) => ReturnType<HandleServerError>;
67
65
  export type CreateAppBuilder<TDependencies extends Record<string, unknown>, TFlags extends BuilderFlags = object> = {
@@ -76,7 +74,7 @@ export type CreateAppBuilder<TDependencies extends Record<string, unknown>, TFla
76
74
  }> & OnceMethod<TFlags, 'useClientError', {
77
75
  useClientError(callback: AppClientErrorCallback<TDependencies>): CreateAppBuilder<TDependencies, WithFlag<TFlags, 'useClientError'>>;
78
76
  }> & OnceMethod<TFlags, 'useServerInit', {
79
- useServerInit(callback: AppServerInitLifecycleCallback<TDependencies>): CreateAppBuilder<TDependencies, WithFlag<TFlags, 'useServerInit'>>;
77
+ useServerInit(callback: AppServerInitLifecycleCallback): CreateAppBuilder<TDependencies, WithFlag<TFlags, 'useServerInit'>>;
80
78
  }> & OnceMethod<TFlags, 'useServer', {
81
79
  useServer(callback: AppServerLifecycleCallback<TDependencies>): CreateAppBuilder<TDependencies, WithFlag<TFlags, 'useServer'>>;
82
80
  }> & OnceMethod<TFlags, 'useServerError', {
@@ -8,7 +8,6 @@ import { executeClientMiddlewares } from './middleware/ClientMiddleware.js';
8
8
  import { useLogger } from '../logger/index.js';
9
9
  const DEFAULT_APP_NAME = '__AzureNetKitGlobalAppContainer__';
10
10
  const clientLifecycleFlags = new WeakMap();
11
- const serverInitLifecycleFlags = new WeakMap();
12
11
  const getRequestContext = () => {
13
12
  try {
14
13
  return RequestContext.current();
@@ -17,13 +16,10 @@ const getRequestContext = () => {
17
16
  return undefined;
18
17
  }
19
18
  };
20
- const getServerRequestContext = (event) => {
19
+ const getServerRequestContext = () => {
21
20
  const requestContext = getRequestContext();
22
21
  if (requestContext)
23
22
  return requestContext;
24
- if (event) {
25
- return { data: {}, event };
26
- }
27
23
  throw new AzureNetKitInternalError('[createApp] RequestContext is not initialized on server.');
28
24
  };
29
25
  const getLifecycleFlags = (appKey, requestContext) => {
@@ -97,6 +93,7 @@ export const createApp = (callback, name = DEFAULT_APP_NAME) => {
97
93
  const dependencies = new Map();
98
94
  const callbacks = {};
99
95
  let clientInitialized = false;
96
+ let serverInitPromise;
100
97
  callback(createBuilder(dependencies, callbacks));
101
98
  const AppProvider = createBoundaryProvider(name, {
102
99
  register: () => {
@@ -171,22 +168,15 @@ export const createApp = (callback, name = DEFAULT_APP_NAME) => {
171
168
  const runServerInit = () => {
172
169
  if (BROWSER)
173
170
  return undefined;
174
- let flags = serverInitLifecycleFlags.get(appKey);
175
- if (!flags) {
176
- flags = {};
177
- serverInitLifecycleFlags.set(appKey, flags);
178
- }
179
- if (flags.serverInit)
180
- return undefined;
181
- flags.serverInit = true;
182
- return callbacks.useServerInit?.({ Container });
171
+ serverInitPromise ??= Promise.resolve().then(() => callbacks.useServerInit?.());
172
+ return serverInitPromise;
183
173
  };
184
174
  const runServerError = ({ error, event, status, message }) => {
185
175
  if (BROWSER)
186
176
  return undefined;
187
177
  return callbacks.useServerError?.({
188
178
  Container,
189
- requestContext: getServerRequestContext(event),
179
+ requestContext: getServerRequestContext(),
190
180
  error,
191
181
  event,
192
182
  status,
@@ -206,7 +196,7 @@ export const createApp = (callback, name = DEFAULT_APP_NAME) => {
206
196
  });
207
197
  };
208
198
  const handle = async ({ event, resolve }) => {
209
- const requestContext = getServerRequestContext(event);
199
+ const requestContext = getServerRequestContext();
210
200
  const flags = getLifecycleFlags(appKey, requestContext);
211
201
  if (!flags.server) {
212
202
  flags.server = true;
@@ -7,27 +7,28 @@ export const executeClientMiddlewares = async (middlewares, navigation) => {
7
7
  const to = navigation?.to?.url ?? page?.url;
8
8
  for (const middleware of middlewares) {
9
9
  let shouldContinue = false;
10
+ let redirectTo;
10
11
  const next = (location) => {
11
12
  shouldContinue = true;
12
- if (location) {
13
- if (navigation) {
14
- navigation?.cancel();
15
- }
16
- return goto(location);
17
- }
13
+ redirectTo = location;
18
14
  };
19
- await middleware({
15
+ const result = middleware({
20
16
  to,
21
17
  from,
22
18
  next,
23
19
  ensureRoute
24
20
  });
21
+ if (result && typeof result.then === 'function')
22
+ await result;
23
+ if (redirectTo) {
24
+ navigation?.cancel();
25
+ await goto(redirectTo);
26
+ return;
27
+ }
25
28
  if (!shouldContinue) {
26
29
  navigation?.cancel();
27
- if (from) {
28
- void goto(from.pathname);
29
- console.warn('Navigation blocked: middleware chain stopped (next() not called).');
30
- }
30
+ console.warn('Navigation blocked: middleware chain stopped (next() not called).');
31
+ return;
31
32
  }
32
33
  }
33
34
  };
@@ -2,7 +2,6 @@ import { RequestContext } from '../../external/edges/ServerContext.js';
2
2
  import { BROWSER } from '../../external/tools/index.js';
3
3
  import { AzureNetKitInternalError } from '../app-error/AppError.js';
4
4
  const clientCache = new Map();
5
- const factoriesCache = new WeakMap();
6
5
  const providerProxyCache = new Map();
7
6
  const clientConstructionStack = [];
8
7
  const clientBootFlags = new Map();
@@ -89,10 +88,6 @@ export const createBoundaryProvider = (name, settings) => {
89
88
  const getFactories = () => {
90
89
  if (factories)
91
90
  return factories;
92
- if (factoriesCache.has(register)) {
93
- factories = factoriesCache.get(register);
94
- return factories;
95
- }
96
91
  const deps = {};
97
92
  const depInstances = new Map();
98
93
  for (const [depName, depProvider] of Object.entries(dependsOn)) {
@@ -107,9 +102,6 @@ export const createBoundaryProvider = (name, settings) => {
107
102
  });
108
103
  }
109
104
  factories = register(deps);
110
- if (BROWSER) {
111
- factoriesCache.set(register, factories);
112
- }
113
105
  return factories;
114
106
  };
115
107
  const providerProxy = new Proxy({}, {