@sveltejs/kit 2.64.0 → 2.65.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.
Files changed (35) hide show
  1. package/package.json +2 -2
  2. package/src/core/postbuild/analyse.js +0 -5
  3. package/src/core/postbuild/prerender.js +2 -0
  4. package/src/core/sync/write_client_manifest.js +5 -0
  5. package/src/exports/public.d.ts +1 -1
  6. package/src/exports/vite/build/build_server.js +43 -57
  7. package/src/exports/vite/build/build_service_worker.js +10 -0
  8. package/src/exports/vite/build/utils.js +0 -8
  9. package/src/exports/vite/index.js +237 -178
  10. package/src/runtime/app/server/remote/command.js +0 -3
  11. package/src/runtime/app/server/remote/form.js +18 -13
  12. package/src/runtime/app/server/remote/prerender.js +28 -34
  13. package/src/runtime/app/server/remote/query.js +105 -94
  14. package/src/runtime/app/server/remote/requested.js +14 -10
  15. package/src/runtime/app/server/remote/shared.js +25 -18
  16. package/src/runtime/client/client.js +25 -15
  17. package/src/runtime/client/remote-functions/command.svelte.js +5 -30
  18. package/src/runtime/client/remote-functions/form.svelte.js +62 -82
  19. package/src/runtime/client/remote-functions/prerender.svelte.js +14 -6
  20. package/src/runtime/client/remote-functions/query/index.js +6 -14
  21. package/src/runtime/client/remote-functions/query/instance.svelte.js +37 -8
  22. package/src/runtime/client/remote-functions/query/proxy.js +3 -3
  23. package/src/runtime/client/remote-functions/query-batch.svelte.js +59 -68
  24. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +20 -6
  25. package/src/runtime/client/remote-functions/shared.svelte.js +76 -59
  26. package/src/runtime/server/page/render.js +20 -83
  27. package/src/runtime/server/page/server_routing.js +20 -15
  28. package/src/runtime/server/remote.js +296 -204
  29. package/src/runtime/server/respond.js +4 -2
  30. package/src/runtime/shared.js +0 -15
  31. package/src/types/global-private.d.ts +3 -3
  32. package/src/types/internal.d.ts +53 -34
  33. package/src/version.js +1 -1
  34. package/types/index.d.ts +4 -4
  35. package/types/index.d.ts.map +1 -1
@@ -26,7 +26,7 @@ import { load_svelte_config, process_config } from '../../core/config/index.js';
26
26
  import { generate_manifest } from '../../core/generate_manifest/index.js';
27
27
  import { build_server_nodes } from './build/build_server.js';
28
28
  import { build_service_worker } from './build/build_service_worker.js';
29
- import { assets_base, find_deps, resolve_symlinks } from './build/utils.js';
29
+ import { find_deps, resolve_symlinks } from './build/utils.js';
30
30
  import { dev } from './dev/index.js';
31
31
  import { preview } from './preview/index.js';
32
32
  import { error_for_missing_config, get_config_aliases, get_env, normalize_id } from './utils.js';
@@ -1034,18 +1034,27 @@ async function kit({ svelte_config }) {
1034
1034
  // see the kit.output.preloadStrategy option for details on why we have multiple options here
1035
1035
  const ext = kit.output.preloadStrategy === 'preload-mjs' ? 'mjs' : 'js';
1036
1036
 
1037
- // We could always use a relative asset base path here, but it's better for performance not to.
1038
- // E.g. Vite generates `new URL('/asset.png', import.meta).href` for a relative path vs just '/asset.png'.
1039
- // That's larger and takes longer to run and also causes an HTML diff between SSR and client
1040
- // causing us to do a more expensive hydration check.
1041
- const client_base =
1042
- kit.paths.relative !== false || kit.paths.assets ? './' : kit_paths_base;
1043
-
1044
1037
  const inline = !ssr && svelte_config.kit.output.bundleStrategy === 'inline';
1045
1038
  const split = ssr || svelte_config.kit.output.bundleStrategy === 'split';
1046
1039
 
1040
+ /** @type {string} */
1041
+ const base = (kit.paths.assets || kit.paths.base) + '/';
1042
+ const root_to_assets = prefix + '/assets/';
1043
+ const assets_to_root =
1044
+ prefix
1045
+ .split('/')
1046
+ .map(() => '..')
1047
+ .join('/') + '/../';
1048
+
1049
+ const relative = kit.paths.relative !== false || !!kit.paths.assets;
1050
+
1047
1051
  new_config = {
1048
- base: ssr ? assets_base(kit) : client_base,
1052
+ // Affects how Vite loads JS assets on the client.
1053
+ // If the initial HTML we render uses an absolute path for assets,
1054
+ // the additional chunks Vite loads must also use an absolute path.
1055
+ // Otherwise, you end up with additional chunks being loaded relative
1056
+ // to the current chunk rather than the root.
1057
+ base: relative ? './' : base,
1049
1058
  build: {
1050
1059
  copyPublicDir: !ssr,
1051
1060
  cssCodeSplit: svelte_config.kit.output.bundleStrategy !== 'inline',
@@ -1094,6 +1103,30 @@ async function kit({ svelte_config }) {
1094
1103
  hoistTransitiveImports: false
1095
1104
  }
1096
1105
  }
1106
+ },
1107
+ experimental: {
1108
+ // Allows us to use relative paths in as many places as we can
1109
+ renderBuiltUrl(filename, { ssr, hostType }) {
1110
+ if (hostType === 'js') {
1111
+ // SSR builds should use an absolute path in JS modules to
1112
+ // match the default Vite behaviour
1113
+ if (ssr) return base + filename;
1114
+
1115
+ // We could always use a relative asset base path here, but it's better for performance not to.
1116
+ // E.g. Vite generates `new URL('/asset.png', import.meta).href` for a relative path vs just '/asset.png'.
1117
+ // That's larger and takes longer to run and also causes an HTML diff between SSR and client
1118
+ // causing us to do a more expensive hydration check.
1119
+ return { relative };
1120
+ }
1121
+
1122
+ // _app/immutable/assets files
1123
+ if (filename.startsWith(root_to_assets)) {
1124
+ return `./${filename.slice(root_to_assets.length)}`;
1125
+ }
1126
+
1127
+ // static dir files
1128
+ return assets_to_root + filename;
1129
+ }
1097
1130
  }
1098
1131
  };
1099
1132
 
@@ -1217,6 +1250,20 @@ async function kit({ svelte_config }) {
1217
1250
  })};\n`
1218
1251
  );
1219
1252
 
1253
+ const server_chunks = Object.values(server_bundle);
1254
+ const assets_path = `${kit.appDir}/immutable/assets`;
1255
+
1256
+ // first, build server nodes without the client manifest so we can analyse it
1257
+ build_server_nodes(
1258
+ out,
1259
+ kit,
1260
+ manifest_data,
1261
+ server_manifest,
1262
+ null,
1263
+ assets_path,
1264
+ server_chunks
1265
+ );
1266
+
1220
1267
  log.info('Analysing routes');
1221
1268
 
1222
1269
  const { metadata } = await analyse({
@@ -1242,191 +1289,205 @@ async function kit({ svelte_config }) {
1242
1289
  metadata.nodes
1243
1290
  );
1244
1291
 
1245
- secondary_build_started = true;
1246
-
1247
- let client_chunks;
1248
-
1249
- try {
1250
- const bundle = /** @type {import('vite').Rollup.RollupOutput} */ (
1251
- await vite.build({
1252
- configFile: vite_config.configFile,
1253
- // CLI args
1254
- mode: vite_config_env.mode,
1255
- logLevel: vite_config.logLevel,
1256
- clearScreen: vite_config.clearScreen,
1257
- build: {
1258
- minify: initial_config.build?.minify,
1259
- assetsInlineLimit: vite_config.build.assetsInlineLimit,
1260
- sourcemap: vite_config.build.sourcemap
1261
- },
1262
- optimizeDeps: {
1263
- force: vite_config.optimizeDeps.force
1264
- }
1265
- })
1266
- );
1267
-
1268
- client_chunks = bundle.output;
1269
- } catch (e) {
1270
- const error =
1271
- e instanceof Error ? e : new Error(/** @type {any} */ (e).message ?? e ?? '<unknown>');
1272
-
1273
- // without this, errors that occur during the secondary build
1274
- // will be logged twice
1275
- throw stackless(error.stack ?? error.message);
1276
- }
1277
-
1278
- // We use `build.ssrEmitAssets` so that asset URLs created from
1279
- // imports in server-only modules correspond to files in the build,
1280
- // but we don't want to copy over CSS imports as these are already
1281
- // accounted for in the client bundle. In most cases it would be
1282
- // a no-op, but for SSR builds `url(...)` paths are handled
1283
- // differently (relative for client, absolute for server)
1284
- // resulting in different hashes, and thus duplication
1285
- const ssr_stylesheets = new Set(
1286
- Object.values(server_manifest)
1287
- .map((chunk) => chunk.css ?? [])
1288
- .flat()
1289
- );
1290
-
1291
- const assets_path = `${kit.appDir}/immutable/assets`;
1292
1292
  const server_assets = `${out}/server/${assets_path}`;
1293
1293
  const client_assets = `${out}/client/${assets_path}`;
1294
1294
 
1295
- if (fs.existsSync(server_assets)) {
1296
- for (const file of fs.readdirSync(server_assets)) {
1297
- const src = `${server_assets}/${file}`;
1298
- const dest = `${client_assets}/${file}`;
1295
+ const skip_client_build = manifest_data.nodes.every(
1296
+ (node) => node.page_options?.csr === false
1297
+ );
1299
1298
 
1300
- if (fs.existsSync(dest) || ssr_stylesheets.has(`${assets_path}/${file}`)) {
1301
- continue;
1302
- }
1299
+ /** @type {Manifest | null} */
1300
+ let client_manifest = null;
1301
+
1302
+ if (!skip_client_build) {
1303
+ let client_chunks;
1304
+
1305
+ try {
1306
+ secondary_build_started = true;
1307
+
1308
+ const bundle = /** @type {import('vite').Rollup.RollupOutput} */ (
1309
+ await vite.build({
1310
+ configFile: vite_config.configFile,
1311
+ // CLI args
1312
+ mode: vite_config_env.mode,
1313
+ logLevel: vite_config.logLevel,
1314
+ clearScreen: vite_config.clearScreen,
1315
+ build: {
1316
+ minify: initial_config.build?.minify,
1317
+ assetsInlineLimit: vite_config.build.assetsInlineLimit,
1318
+ sourcemap: vite_config.build.sourcemap
1319
+ },
1320
+ optimizeDeps: {
1321
+ force: vite_config.optimizeDeps.force
1322
+ }
1323
+ })
1324
+ );
1303
1325
 
1304
- if (file.endsWith('.css')) {
1305
- // make absolute paths in CSS relative, for portability
1306
- const content = fs
1307
- .readFileSync(src, 'utf-8')
1308
- .replaceAll(`${kit.paths.base}/${assets_path}`, '.');
1326
+ secondary_build_started = false;
1309
1327
 
1310
- fs.writeFileSync(src, content);
1311
- }
1328
+ client_chunks = bundle.output;
1329
+ } catch (e) {
1330
+ const error =
1331
+ e instanceof Error
1332
+ ? e
1333
+ : new Error(/** @type {any} */ (e).message ?? e ?? '<unknown>');
1312
1334
 
1313
- copy(src, dest);
1335
+ // without this, errors that occur during the secondary build
1336
+ // will be logged twice
1337
+ throw stackless(error.stack ?? error.message);
1314
1338
  }
1315
- }
1316
1339
 
1317
- /** @type {Manifest} */
1318
- const client_manifest = JSON.parse(read(`${out}/client/.vite/manifest.json`));
1319
-
1320
- /**
1321
- * @param {string} entry
1322
- * @param {boolean} [add_dynamic_css]
1323
- */
1324
- const deps_of = (entry, add_dynamic_css = false) =>
1325
- find_deps(client_manifest, posixify(path.relative('.', entry)), add_dynamic_css);
1326
-
1327
- if (svelte_config.kit.output.bundleStrategy === 'split') {
1328
- const start = deps_of(`${runtime_directory}/client/entry.js`);
1329
- const app = deps_of(`${out_dir}/generated/client-optimized/app.js`);
1330
-
1331
- build_data.client = {
1332
- start: start.file,
1333
- app: app.file,
1334
- imports: [...start.imports, ...app.imports],
1335
- stylesheets: [...start.stylesheets, ...app.stylesheets],
1336
- fonts: [...start.fonts, ...app.fonts],
1337
- uses_env_dynamic_public: client_chunks.some(
1338
- (chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public]
1339
- )
1340
- };
1340
+ // We use `build.ssrEmitAssets` so that asset URLs created from
1341
+ // imports in server-only modules correspond to files in the build,
1342
+ // but we don't want to copy over CSS imports as these are already
1343
+ // accounted for in the client bundle. In most cases it would be
1344
+ // a no-op, but for SSR builds `url(...)` paths are handled
1345
+ // differently (relative for client, absolute for server)
1346
+ // resulting in different hashes, and thus duplication
1347
+ const ssr_stylesheets = new Set(
1348
+ Object.values(server_manifest)
1349
+ .map((chunk) => chunk.css ?? [])
1350
+ .flat()
1351
+ );
1341
1352
 
1342
- // In case of server-side route resolution, we create a purpose-built route manifest that is
1343
- // similar to that on the client, with as much information computed upfront so that we
1344
- // don't need to include any code of the actual routes in the server bundle.
1345
- if (svelte_config.kit.router.resolution === 'server') {
1346
- const nodes = manifest_data.nodes.map((node, i) => {
1347
- if (node.component || node.universal) {
1348
- const entry = `${out_dir}/generated/client-optimized/nodes/${i}.js`;
1349
- const deps = deps_of(entry, true);
1350
- const file = resolve_symlinks(
1351
- client_manifest,
1352
- `${out_dir}/generated/client-optimized/nodes/${i}.js`
1353
- ).chunk.file;
1354
-
1355
- return { file, css: deps.stylesheets };
1353
+ if (fs.existsSync(server_assets)) {
1354
+ for (const file of fs.readdirSync(server_assets)) {
1355
+ const src = `${server_assets}/${file}`;
1356
+ const dest = `${client_assets}/${file}`;
1357
+
1358
+ if (fs.existsSync(dest) || ssr_stylesheets.has(`${assets_path}/${file}`)) {
1359
+ continue;
1356
1360
  }
1357
- });
1358
- build_data.client.nodes = nodes.map((node) => node?.file);
1359
- build_data.client.css = nodes.map((node) => node?.css);
1360
-
1361
- build_data.client.routes = compact(
1362
- manifest_data.routes.map((route) => {
1363
- if (!route.page) return;
1364
-
1365
- return {
1366
- id: route.id,
1367
- pattern: route.pattern,
1368
- params: route.params,
1369
- layouts: route.page.layouts.map((l) =>
1370
- l !== undefined ? [metadata.nodes[l].has_server_load, l] : undefined
1371
- ),
1372
- errors: route.page.errors,
1373
- leaf: [metadata.nodes[route.page.leaf].has_server_load, route.page.leaf]
1374
- };
1375
- })
1376
- );
1361
+
1362
+ copy(src, dest);
1363
+ }
1377
1364
  }
1378
- } else {
1379
- const start = deps_of(`${runtime_directory}/client/bundle.js`);
1380
-
1381
- build_data.client = {
1382
- start: start.file,
1383
- imports: start.imports,
1384
- stylesheets: start.stylesheets,
1385
- fonts: start.fonts,
1386
- uses_env_dynamic_public: client_chunks.some(
1387
- (chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public]
1388
- )
1389
- };
1390
1365
 
1391
- if (svelte_config.kit.output.bundleStrategy === 'inline') {
1392
- const style = /** @type {import('vite').Rollup.OutputAsset} */ (
1393
- client_chunks.find(
1394
- (chunk) =>
1395
- chunk.type === 'asset' &&
1396
- chunk.names.length === 1 &&
1397
- chunk.names[0] === 'style.css'
1366
+ /** @type {Manifest} */
1367
+ const manifest = (client_manifest = JSON.parse(
1368
+ read(`${out}/client/.vite/manifest.json`)
1369
+ ));
1370
+
1371
+ /**
1372
+ * @param {string} entry
1373
+ * @param {boolean} [add_dynamic_css]
1374
+ */
1375
+ const deps_of = (entry, add_dynamic_css = false) =>
1376
+ find_deps(manifest, posixify(path.relative('.', entry)), add_dynamic_css);
1377
+
1378
+ if (svelte_config.kit.output.bundleStrategy === 'split') {
1379
+ const start = deps_of(`${runtime_directory}/client/entry.js`);
1380
+ const app = deps_of(`${out_dir}/generated/client-optimized/app.js`);
1381
+
1382
+ build_data.client = {
1383
+ start: start.file,
1384
+ app: app.file,
1385
+ imports: [...start.imports, ...app.imports],
1386
+ stylesheets: [...start.stylesheets, ...app.stylesheets],
1387
+ fonts: [...start.fonts, ...app.fonts],
1388
+ uses_env_dynamic_public: client_chunks.some(
1389
+ (chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public]
1398
1390
  )
1399
- );
1391
+ };
1400
1392
 
1401
- build_data.client.inline = {
1402
- script: read(`${out}/client/${start.file}`),
1403
- style: /** @type {string | undefined} */ (style?.source)
1393
+ // In case of server-side route resolution, we create a purpose-built route manifest that is
1394
+ // similar to that on the client, with as much information computed upfront so that we
1395
+ // don't need to include any code of the actual routes in the server bundle.
1396
+ if (svelte_config.kit.router.resolution === 'server') {
1397
+ const nodes = manifest_data.nodes.map((node, i) => {
1398
+ if (node.component || node.universal) {
1399
+ const entry = `${out_dir}/generated/client-optimized/nodes/${i}.js`;
1400
+ const deps = deps_of(entry, true);
1401
+ const file = resolve_symlinks(
1402
+ manifest,
1403
+ `${out_dir}/generated/client-optimized/nodes/${i}.js`
1404
+ ).chunk.file;
1405
+
1406
+ return { file, css: deps.stylesheets };
1407
+ }
1408
+ });
1409
+ build_data.client.nodes = nodes.map((node) => node?.file);
1410
+ build_data.client.css = nodes.map((node) => node?.css);
1411
+
1412
+ build_data.client.routes = compact(
1413
+ manifest_data.routes.map((route) => {
1414
+ if (!route.page) return;
1415
+
1416
+ return {
1417
+ id: route.id,
1418
+ pattern: route.pattern,
1419
+ params: route.params,
1420
+ layouts: route.page.layouts.map((l) =>
1421
+ l !== undefined ? [metadata.nodes[l].has_server_load, l] : undefined
1422
+ ),
1423
+ errors: route.page.errors,
1424
+ leaf: [metadata.nodes[route.page.leaf].has_server_load, route.page.leaf]
1425
+ };
1426
+ })
1427
+ );
1428
+ }
1429
+ } else {
1430
+ const start = deps_of(`${runtime_directory}/client/bundle.js`);
1431
+
1432
+ build_data.client = {
1433
+ start: start.file,
1434
+ imports: start.imports,
1435
+ stylesheets: start.stylesheets,
1436
+ fonts: start.fonts,
1437
+ uses_env_dynamic_public: client_chunks.some(
1438
+ (chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public]
1439
+ )
1404
1440
  };
1441
+
1442
+ if (svelte_config.kit.output.bundleStrategy === 'inline') {
1443
+ const style = /** @type {import('vite').Rollup.OutputAsset} */ (
1444
+ client_chunks.find(
1445
+ (chunk) =>
1446
+ chunk.type === 'asset' &&
1447
+ chunk.names.length === 1 &&
1448
+ chunk.names[0] === 'style.css'
1449
+ )
1450
+ );
1451
+
1452
+ build_data.client.inline = {
1453
+ script: read(`${out}/client/${start.file}`),
1454
+ style: /** @type {string | undefined} */ (style?.source)
1455
+ };
1456
+
1457
+ // the bundle and stylesheet are inlined into the page, so the
1458
+ // emitted files are never loaded
1459
+ fs.unlinkSync(`${out}/client/${start.file}`);
1460
+ fs.rmSync(`${out}/client/${start.file}.map`, { force: true });
1461
+ if (style) fs.unlinkSync(`${out}/client/${style.fileName}`);
1462
+ }
1405
1463
  }
1406
- }
1407
1464
 
1408
- // regenerate manifest now that we have client entry...
1409
- fs.writeFileSync(
1410
- manifest_path,
1411
- `export const manifest = ${generate_manifest({
1412
- build_data,
1413
- prerendered: [],
1414
- relative_path: '.',
1415
- routes: manifest_data.routes,
1416
- remotes
1417
- })};\n`
1418
- );
1465
+ // regenerate manifest now that we have client entry...
1466
+ fs.writeFileSync(
1467
+ manifest_path,
1468
+ `export const manifest = ${generate_manifest({
1469
+ build_data,
1470
+ prerendered: [],
1471
+ relative_path: '.',
1472
+ routes: manifest_data.routes,
1473
+ remotes
1474
+ })};\n`
1475
+ );
1419
1476
 
1420
- // regenerate nodes with the client manifest...
1421
- build_server_nodes(
1422
- out,
1423
- kit,
1424
- manifest_data,
1425
- server_manifest,
1426
- client_manifest,
1427
- assets_path,
1428
- client_chunks
1429
- );
1477
+ // regenerate nodes with the client manifest...
1478
+ build_server_nodes(
1479
+ out,
1480
+ kit,
1481
+ manifest_data,
1482
+ server_manifest,
1483
+ manifest,
1484
+ assets_path,
1485
+ client_chunks
1486
+ );
1487
+ } else {
1488
+ copy(server_assets, client_assets);
1489
+ copy(kit.files.assets, `${out}/client`);
1490
+ }
1430
1491
 
1431
1492
  // ...and prerender
1432
1493
  const { prerendered, prerender_map } = await prerender({
@@ -1479,7 +1540,7 @@ async function kit({ svelte_config }) {
1479
1540
  manifest_data,
1480
1541
  service_worker_entry_file,
1481
1542
  prerendered,
1482
- client_manifest,
1543
+ client_manifest ?? server_manifest,
1483
1544
  explicit_env_config
1484
1545
  );
1485
1546
  }
@@ -1514,8 +1575,6 @@ async function kit({ svelte_config }) {
1514
1575
  `See ${link} to learn how to configure your app to run on the platform of your choosing`
1515
1576
  );
1516
1577
  }
1517
-
1518
- secondary_build_started = false;
1519
1578
  };
1520
1579
  }
1521
1580
  },
@@ -77,9 +77,6 @@ export function command(validate_or_fn, maybe_fn) {
77
77
  );
78
78
  }
79
79
 
80
- state.remote.refreshes ??= new Map();
81
- state.remote.reconnects ??= new Map();
82
-
83
80
  const promise = Promise.resolve(
84
81
  run_remote_function(event, state, true, () => validate(arg), fn)
85
82
  );
@@ -11,7 +11,7 @@ import {
11
11
  normalize_issue,
12
12
  flatten_issues
13
13
  } from '../../../form-utils.js';
14
- import { get_cache, run_remote_function } from './shared.js';
14
+ import { get_cache, get_implicit_lookup, run_remote_function } from './shared.js';
15
15
  import { ValidationError } from '@sveltejs/kit/internal';
16
16
 
17
17
  /**
@@ -136,9 +136,6 @@ export function form(validate_or_fn, maybe_fn) {
136
136
  data = validated.value;
137
137
  }
138
138
 
139
- state.remote.refreshes ??= new Map();
140
- state.remote.reconnects ??= new Map();
141
-
142
139
  const issue = create_issues();
143
140
 
144
141
  try {
@@ -161,7 +158,12 @@ export function form(validate_or_fn, maybe_fn) {
161
158
  // We don't need to care about args or deduplicating calls, because uneval results are only relevant in full page reloads
162
159
  // where only one form submission is active at the same time
163
160
  if (!event.isRemoteRequest) {
164
- get_cache(__, state)[''] ??= { serialize: true, data: output };
161
+ const cache = get_cache(__, state);
162
+ cache[''] ??= output;
163
+
164
+ // register under the client-side action id so the output is serialized
165
+ // into the page, allowing the hydrated client to restore `result`/`issues`/`input`
166
+ get_implicit_lookup(__, state)[__.action_id ?? __.id] = () => cache[''];
165
167
  }
166
168
 
167
169
  return output;
@@ -177,28 +179,30 @@ export function form(validate_or_fn, maybe_fn) {
177
179
 
178
180
  Object.defineProperty(instance, 'fields', {
179
181
  get() {
182
+ // the form instance is created once per module and shared across requests,
183
+ // so the current request's state has to be resolved at access time
180
184
  return create_field_proxy(
181
185
  {},
182
- () => get_cache(__)?.['']?.data?.input ?? {},
186
+ () => get_cache(__, get_request_store().state)?.['']?.input ?? {},
183
187
  (path, value) => {
184
- const cache = get_cache(__);
188
+ const cache = get_cache(__, get_request_store().state);
185
189
  const entry = cache[''];
186
190
 
187
- if (entry?.data?.submission) {
191
+ if (entry?.submission) {
188
192
  // don't override a submission
189
193
  return;
190
194
  }
191
195
 
192
196
  if (path.length === 0) {
193
- (cache[''] ??= { serialize: true, data: {} }).data.input = value;
197
+ (cache[''] ??= {}).input = value;
194
198
  return;
195
199
  }
196
200
 
197
- const input = entry?.data?.input ?? {};
201
+ const input = entry?.input ?? {};
198
202
  deep_set(input, path.map(String), value);
199
- (cache[''] ??= { serialize: true, data: {} }).data.input = input;
203
+ (cache[''] ??= {}).input = input;
200
204
  },
201
- () => flatten_issues(get_cache(__)?.['']?.data?.issues ?? [])
205
+ () => flatten_issues(get_cache(__, get_request_store().state)?.['']?.issues ?? [])
202
206
  );
203
207
  }
204
208
  });
@@ -220,7 +224,7 @@ export function form(validate_or_fn, maybe_fn) {
220
224
  Object.defineProperty(instance, 'result', {
221
225
  get() {
222
226
  try {
223
- return get_cache(__)?.['']?.data?.result;
227
+ return get_cache(__, get_request_store().state)?.['']?.result;
224
228
  } catch {
225
229
  return undefined;
226
230
  }
@@ -264,6 +268,7 @@ export function form(validate_or_fn, maybe_fn) {
264
268
  if (!instance) {
265
269
  instance = create_instance(key);
266
270
  instance.__.id = `${__.id}/${encodeURIComponent(JSON.stringify(key))}`;
271
+ instance.__.action_id = `${__.id}/${JSON.stringify(key)}`;
267
272
  instance.__.name = __.name;
268
273
 
269
274
  state.remote.forms.set(cache_key, instance);