@absolutejs/absolute 0.19.0-beta.741 → 0.19.0-beta.743

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.
@@ -60,6 +60,21 @@ var __legacyMetadataTS = (k, v) => {
60
60
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
61
61
  var __require = import.meta.require;
62
62
 
63
+ // src/angular/httpTransferCache.ts
64
+ var ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER = "x-skip-transfer-cache", buildAbsoluteHttpTransferCacheOptions = (options = {}) => {
65
+ const {
66
+ filter: userFilter,
67
+ skipHeader = ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER,
68
+ ...angularOptions
69
+ } = options;
70
+ return {
71
+ includePostRequests: false,
72
+ includeRequestsWithAuthHeaders: false,
73
+ ...angularOptions,
74
+ filter: (request) => !request.headers.has(skipHeader) && (userFilter?.(request) ?? true)
75
+ };
76
+ };
77
+
63
78
  // src/constants.ts
64
79
  var ANGULAR_INIT_TIMEOUT_MS = 500, ANSI_ESCAPE_CODE = 27, ANSI_ESCAPE_LENGTH = 3, ASCII_SPACE = 32, BASE_36_RADIX = 36, BUN_BUILD_WARNING_SUPPRESSION = "wildcard sideEffects are not supported yet", BODY_SLICE_LENGTH = 2000, BYTES_PER_KILOBYTE = 1024, CLI_ARGS_OFFSET = 3, CSS_ERROR_RESOLVE_DELAY_MS = 50, CSS_MAX_CHECK_ATTEMPTS = 10, CSS_MAX_PARSE_TIMEOUT_MS = 500, CSS_SHEET_READY_TIMEOUT_MS = 100, DEFAULT_CHUNK_SIZE = 16384, DEFAULT_DEBOUNCE_MS = 15, DEFAULT_PORT = 3000, DEV_SERVER_RESTART_DEBOUNCE_MS = 100, DOM_UPDATE_DELAY_MS = 50, FILE_PROTOCOL_PREFIX_LENGTH = 7, FOCUS_ID_PREFIX_LENGTH = 3, FOCUS_IDX_PREFIX_LENGTH = 4, FOCUS_NAME_PREFIX_LENGTH = 5, HMR_UPDATE_TIMEOUT_MS = 2000, HOOK_SIGNATURE_LENGTH = 12, EXCLUDE_LAST_OFFSET = -1, HTTP_STATUS_OK = 200, HTTP_STATUS_BAD_REQUEST = 400, HTTP_STATUS_NOT_FOUND = 404, HOURS_IN_DAY = 24, HOURS_IN_HALF_DAY = 12, IMAGE_DEFAULT_DEVICE_SIZES, IMAGE_DEFAULT_IMAGE_SIZES, IMAGE_DEFAULT_QUALITY = 75, IMAGE_GLOB_SUFFIX_LENGTH = 2, MAX_ERROR_LENGTH = 200, MAX_RECONNECT_ATTEMPTS = 60, MILLISECONDS_IN_A_SECOND = 1000, MINUTES_IN_AN_HOUR = 60, SECONDS_IN_A_MINUTE = 60, MILLISECONDS_IN_A_MINUTE, MILLISECONDS_IN_A_DAY, OVERLAY_FADE_DURATION_MS = 150, PING_INTERVAL_MS = 30000, RAF_BATCH_COUNT = 3, RANDOM_ID_END_INDEX = 11, REBUILD_BATCH_DELAY_MS = 10, REBUILD_RELOAD_DELAY_MS = 200, RECONNECT_INITIAL_DELAY_MS = 500, RECONNECT_POLL_INTERVAL_MS = 300, REACT_STREAM_SLOT_FAST_DELAY_MS = 5, REACT_STREAM_SLOT_SLOW_DELAY_MS = 20, SIGINT_EXIT_CODE = 130, SIGTERM_EXIT_CODE = 143, SVELTE_CSS_LOAD_TIMEOUT_MS = 500, TIME_PRECISION = 2, TWO_THIRDS, UNFOUND_INDEX = -1, WEBSOCKET_NORMAL_CLOSURE = 1000, WORKSPACE_COMMAND_ARGS_OFFSET = 3, WORKSPACE_FAILURE_LOG_PRINT_LIMIT = 30, WORKSPACE_FAILURE_RECENT_LOG_LIMIT = 60, WORKSPACE_READY_ATTEMPT_TIMEOUT_MS = 5000, WORKSPACE_READY_PROBE_INTERVAL_MS = 250, WORKSPACE_READY_TIMEOUT_MS = 30000, WORKSPACE_SHUTDOWN_TIMEOUT_MS = 1e4, WORKSPACE_TUI_DEFAULT_HEIGHT = 28, WORKSPACE_TUI_DEFAULT_WIDTH = 100, WORKSPACE_TUI_ESCAPE_SEQUENCE_TIMEOUT_MS = 30, WORKSPACE_TUI_FOOTER_LINE_COUNT = 3, WORKSPACE_TUI_MIN_LOG_HEIGHT = 3, WORKSPACE_TUI_MIN_SERVICE_NAME_WIDTH = 7, WORKSPACE_TUI_MIN_TARGET_WIDTH = 8, WORKSPACE_TUI_MIN_WRAP_WIDTH = 12, WORKSPACE_TUI_PROMPT_CURSOR_OFFSET = 3, WORKSPACE_TUI_RECENT_LOG_LIMIT = 40, WORKSPACE_TUI_RENDER_DEBOUNCE_MS = 16, WORKSPACE_TUI_STATUS_WIDTH = 10, WORKSPACE_TUI_TARGET_PADDING_WIDTH = 6, WORKSPACE_TUI_VISIBILITY_WIDTH = 8;
65
80
  var init_constants = __esm(() => {
@@ -399,13 +414,19 @@ var initDominoAdapter = (platformServer) => {
399
414
  APP_BASE_HREF: common.APP_BASE_HREF,
400
415
  bootstrapApplication: platformBrowser.bootstrapApplication,
401
416
  DomSanitizer: platformBrowser.DomSanitizer,
417
+ ENVIRONMENT_INITIALIZER: core.ENVIRONMENT_INITIALIZER,
418
+ inject: core.inject,
402
419
  provideClientHydration: platformBrowser.provideClientHydration,
403
420
  provideServerRendering: platformServer.provideServerRendering,
404
421
  provideZonelessChangeDetection: core.provideZonelessChangeDetection,
405
422
  reflectComponentType: core.reflectComponentType,
406
423
  renderApplication: platformServer.renderApplication,
424
+ REQUEST: core.REQUEST,
425
+ REQUEST_CONTEXT: core.REQUEST_CONTEXT,
426
+ RESPONSE_INIT: core.RESPONSE_INIT,
407
427
  Sanitizer: core.Sanitizer,
408
- SecurityContext: core.SecurityContext
428
+ SecurityContext: core.SecurityContext,
429
+ withHttpTransferCacheOptions: platformBrowser.withHttpTransferCacheOptions
409
430
  };
410
431
  }, angularDeps = null, getAngularDeps = () => {
411
432
  if (!angularDeps) {
@@ -429,6 +450,15 @@ var requireCurrentIslandRegistry = () => {
429
450
  globalThis.__absoluteIslandRegistry = registry;
430
451
  };
431
452
 
453
+ // src/angular/requestProviders.ts
454
+ import { REQUEST, REQUEST_CONTEXT, RESPONSE_INIT } from "@angular/core";
455
+ var buildRequestProviders = (deps, request, requestContext, responseInit) => [
456
+ { provide: deps.REQUEST, useValue: request ?? null },
457
+ { provide: deps.REQUEST_CONTEXT, useValue: requestContext ?? null },
458
+ { provide: deps.RESPONSE_INIT, useValue: responseInit ?? null }
459
+ ];
460
+ var init_requestProviders = () => {};
461
+
432
462
  // src/angular/ssrRender.ts
433
463
  var routePropsCache, cacheRouteData = (pagePath, data) => {
434
464
  const cacheKey = pagePath.split("?")[0] ?? pagePath;
@@ -442,18 +472,24 @@ var routePropsCache, cacheRouteData = (pagePath, data) => {
442
472
  APP_BASE_HREF: common?.APP_BASE_HREF ?? baseDeps.APP_BASE_HREF,
443
473
  bootstrapApplication: platformBrowser?.bootstrapApplication ?? baseDeps.bootstrapApplication,
444
474
  DomSanitizer: platformBrowser?.DomSanitizer ?? baseDeps.DomSanitizer,
475
+ ENVIRONMENT_INITIALIZER: core.ENVIRONMENT_INITIALIZER ?? baseDeps.ENVIRONMENT_INITIALIZER,
476
+ inject: core.inject ?? baseDeps.inject,
445
477
  provideClientHydration: platformBrowser?.provideClientHydration ?? baseDeps.provideClientHydration,
446
478
  provideServerRendering: platformServer?.provideServerRendering ?? baseDeps.provideServerRendering,
447
479
  provideZonelessChangeDetection: core.provideZonelessChangeDetection,
448
480
  reflectComponentType: core.reflectComponentType,
449
481
  renderApplication: platformServer?.renderApplication ?? baseDeps.renderApplication,
482
+ REQUEST: core.REQUEST ?? baseDeps.REQUEST,
483
+ REQUEST_CONTEXT: core.REQUEST_CONTEXT ?? baseDeps.REQUEST_CONTEXT,
484
+ RESPONSE_INIT: core.RESPONSE_INIT ?? baseDeps.RESPONSE_INIT,
450
485
  Sanitizer: core.Sanitizer,
451
- SecurityContext: core.SecurityContext
486
+ SecurityContext: core.SecurityContext,
487
+ withHttpTransferCacheOptions: platformBrowser?.withHttpTransferCacheOptions ?? baseDeps.withHttpTransferCacheOptions
452
488
  };
453
- }, buildProviders = (deps, sanitizer, maybeProps, tokenMap, userProviders = []) => {
489
+ }, buildProviders = (deps, sanitizer, maybeProps, tokenMap, request, requestContext, responseInit, userProviders = []) => {
454
490
  const providers = [
455
491
  deps.provideServerRendering(),
456
- deps.provideClientHydration(),
492
+ deps.provideClientHydration(deps.withHttpTransferCacheOptions(buildAbsoluteHttpTransferCacheOptions())),
457
493
  deps.provideZonelessChangeDetection(),
458
494
  { provide: deps.APP_BASE_HREF, useValue: "/" },
459
495
  {
@@ -461,6 +497,7 @@ var routePropsCache, cacheRouteData = (pagePath, data) => {
461
497
  useValue: sanitizer
462
498
  },
463
499
  { provide: deps.Sanitizer, useValue: sanitizer },
500
+ ...buildRequestProviders(deps, request, requestContext, responseInit),
464
501
  ...userProviders
465
502
  ];
466
503
  if (!maybeProps) {
@@ -543,6 +580,7 @@ var routePropsCache, cacheRouteData = (pagePath, data) => {
543
580
  };
544
581
  var init_ssrRender = __esm(() => {
545
582
  init_registerClientScript();
583
+ init_requestProviders();
546
584
  routePropsCache = new Map;
547
585
  selectorCache = new Map;
548
586
  });
@@ -608,11 +646,11 @@ var angularIslandSelector = "abs-angular-island", getAngularIslandSelector = (_i
608
646
  const componentName = typeof component.name === "string" && component.name.length > 0 ? component.name : "AngularIsland";
609
647
  return `${componentName}:${JSON.stringify(props)}`;
610
648
  }, buildAngularIslandWrapperMetadata = async (component, islandId, wrapperKey) => {
611
- const { Component, InjectionToken, inject } = await import("@angular/core");
649
+ const { Component, InjectionToken: InjectionToken2, inject } = await import("@angular/core");
612
650
  const { NgComponentOutlet } = await import("@angular/common");
613
651
  const deps = await getAngularDeps();
614
652
  const selector = getAngularIslandSelector(islandId);
615
- const propsToken = new InjectionToken(`${wrapperKey}:props`);
653
+ const propsToken = new InjectionToken2(`${wrapperKey}:props`);
616
654
 
617
655
  class AngularIslandWrapperComponent {
618
656
  component = component;
@@ -3227,6 +3265,74 @@ var computeConfigHash = () => {
3227
3265
  }
3228
3266
  }
3229
3267
  return;
3268
+ }, resolveSourceFile = (candidate) => {
3269
+ const candidates = candidate.match(/\.[cm]?[tj]sx?$/) ? [candidate] : [
3270
+ `${candidate}.ts`,
3271
+ `${candidate}.tsx`,
3272
+ `${candidate}.js`,
3273
+ `${candidate}.jsx`,
3274
+ join5(candidate, "index.ts"),
3275
+ join5(candidate, "index.tsx"),
3276
+ join5(candidate, "index.js"),
3277
+ join5(candidate, "index.jsx")
3278
+ ];
3279
+ return candidates.find((file) => existsSync5(file));
3280
+ }, sourceTreeUsesLegacyAngularAnimations = async (entryPath, rootDir) => {
3281
+ const baseDir = resolve6(rootDir);
3282
+ const tsconfigAliases = readTsconfigPathAliases();
3283
+ const transpiler2 = new Bun.Transpiler({ loader: "tsx" });
3284
+ const visited = new Set;
3285
+ const resolveLocalImport = (specifier, fromDir) => {
3286
+ if (specifier.startsWith(".") || specifier.startsWith("/")) {
3287
+ return resolveSourceFile(resolve6(fromDir, specifier));
3288
+ }
3289
+ const aliased = matchTsconfigAlias(specifier, tsconfigAliases.aliases, tsconfigAliases.baseUrl, resolveSourceFile);
3290
+ if (aliased)
3291
+ return aliased;
3292
+ try {
3293
+ const resolved = Bun.resolveSync(specifier, fromDir);
3294
+ if (resolved.includes("/node_modules/"))
3295
+ return;
3296
+ const absolute = resolve6(resolved);
3297
+ if (!absolute.startsWith(baseDir))
3298
+ return;
3299
+ return resolveSourceFile(absolute);
3300
+ } catch {
3301
+ return;
3302
+ }
3303
+ };
3304
+ const visit = async (filePath) => {
3305
+ const actualPath = resolveSourceFile(filePath);
3306
+ if (!actualPath)
3307
+ return false;
3308
+ const resolved = resolve6(actualPath);
3309
+ if (visited.has(resolved))
3310
+ return false;
3311
+ visited.add(resolved);
3312
+ let sourceCode;
3313
+ try {
3314
+ sourceCode = await fs.readFile(resolved, "utf-8");
3315
+ } catch {
3316
+ return false;
3317
+ }
3318
+ let imports;
3319
+ try {
3320
+ imports = transpiler2.scanImports(sourceCode);
3321
+ } catch {
3322
+ return false;
3323
+ }
3324
+ for (const imp of imports) {
3325
+ if (imp.path === "@angular/animations")
3326
+ return true;
3327
+ }
3328
+ for (const imp of imports) {
3329
+ const importedPath = resolveLocalImport(imp.path, dirname4(resolved));
3330
+ if (importedPath && await visit(importedPath))
3331
+ return true;
3332
+ }
3333
+ return false;
3334
+ };
3335
+ return visit(entryPath);
3230
3336
  }, resolveDevClientDir = () => {
3231
3337
  const projectRoot = process.cwd();
3232
3338
  const fromSource = resolve6(import.meta.dir, "../dev/client");
@@ -3708,6 +3814,7 @@ ${fields}
3708
3814
  const allOutputs = [];
3709
3815
  const visited = new Set;
3710
3816
  const baseDir = resolve6(rootDir ?? process.cwd());
3817
+ let usesLegacyAnimations = false;
3711
3818
  const angularTranspiler = new Bun.Transpiler({
3712
3819
  loader: "ts",
3713
3820
  tsconfig: JSON.stringify({
@@ -3718,7 +3825,7 @@ ${fields}
3718
3825
  })
3719
3826
  });
3720
3827
  const tsconfigAliases = readTsconfigPathAliases();
3721
- const resolveSourceFile = (candidate) => {
3828
+ const resolveSourceFile2 = (candidate) => {
3722
3829
  const candidates = candidate.match(/\.[cm]?[tj]sx?$/) ? [candidate] : [
3723
3830
  `${candidate}.ts`,
3724
3831
  `${candidate}.tsx`,
@@ -3733,9 +3840,9 @@ ${fields}
3733
3840
  };
3734
3841
  const resolveLocalImport = (specifier, fromDir) => {
3735
3842
  if (specifier.startsWith(".") || specifier.startsWith("/")) {
3736
- return resolveSourceFile(resolve6(fromDir, specifier));
3843
+ return resolveSourceFile2(resolve6(fromDir, specifier));
3737
3844
  }
3738
- const aliased = matchTsconfigAlias(specifier, tsconfigAliases.aliases, tsconfigAliases.baseUrl, resolveSourceFile);
3845
+ const aliased = matchTsconfigAlias(specifier, tsconfigAliases.aliases, tsconfigAliases.baseUrl, resolveSourceFile2);
3739
3846
  if (aliased)
3740
3847
  return aliased;
3741
3848
  try {
@@ -3745,7 +3852,7 @@ ${fields}
3745
3852
  const absolute = resolve6(resolved);
3746
3853
  if (!absolute.startsWith(baseDir))
3747
3854
  return;
3748
- return resolveSourceFile(absolute);
3855
+ return resolveSourceFile2(absolute);
3749
3856
  } catch {
3750
3857
  return;
3751
3858
  }
@@ -3823,6 +3930,9 @@ ${fields}
3823
3930
  if (importMatch[1])
3824
3931
  localImports.push(importMatch[1]);
3825
3932
  }
3933
+ if (localImports.includes("@angular/animations")) {
3934
+ usesLegacyAnimations = true;
3935
+ }
3826
3936
  const localImportPaths = localImports.map((specifier) => {
3827
3937
  const resolved2 = resolveLocalImport(specifier, inputDir);
3828
3938
  if (!resolved2)
@@ -3845,6 +3955,18 @@ ${fields}
3845
3955
  await Promise.all(localImportPaths.map((importPath) => transpileFile(importPath)));
3846
3956
  };
3847
3957
  await transpileFile(inputPath);
3958
+ const entryOutputPath = toOutputPath(entryPath);
3959
+ if (existsSync5(entryOutputPath)) {
3960
+ const entryOutput = await fs.readFile(entryOutputPath, "utf-8");
3961
+ const withoutLegacyFlag = entryOutput.replace(/\nexport const __ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ = true;\n?/g, `
3962
+ `);
3963
+ const nextEntryOutput = usesLegacyAnimations ? `${withoutLegacyFlag}
3964
+ export const __ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ = true;
3965
+ ` : withoutLegacyFlag;
3966
+ if (nextEntryOutput !== entryOutput) {
3967
+ await fs.writeFile(entryOutputPath, nextEntryOutput, "utf-8");
3968
+ }
3969
+ }
3848
3970
  return allOutputs;
3849
3971
  }, compileAngular = async (entryPoints, outRoot, hmr = false, stylePreprocessors) => {
3850
3972
  const compiledParent = join5(outRoot, "generated");
@@ -3906,10 +4028,11 @@ ${fields}
3906
4028
  return fallback;
3907
4029
  };
3908
4030
  const componentClassName = detectExportedComponentClass(original, `${toPascal(fileBase)}Component`);
4031
+ const usesLegacyAnimations = await sourceTreeUsesLegacyAngularAnimations(resolvedEntry, outRoot);
3909
4032
  const serverContentHash = Bun.hash(original).toString(BASE_36_RADIX);
3910
4033
  const cachedWrapper = wrapperOutputCache.get(resolvedEntry);
3911
4034
  const clientFile = join5(indexesDir, jsName);
3912
- if (hmr && cachedWrapper && cachedWrapper.serverHash === serverContentHash && existsSync5(clientFile)) {
4035
+ if (hmr && cachedWrapper && cachedWrapper.serverHash === serverContentHash && existsSync5(clientFile) && (usesLegacyAnimations || !original.includes("__ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__")) && (!usesLegacyAnimations || original.includes("__ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__"))) {
3913
4036
  return {
3914
4037
  clientPath: clientFile,
3915
4038
  indexUnchanged: true,
@@ -3917,6 +4040,8 @@ ${fields}
3917
4040
  };
3918
4041
  }
3919
4042
  let rewritten = original;
4043
+ rewritten = rewritten.replace(/\nexport const __ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ = true;\n?/g, `
4044
+ `);
3920
4045
  if (!rewritten.includes(`import '@angular/compiler';`)) {
3921
4046
  rewritten = `import '@angular/compiler';
3922
4047
  ${rewritten}`;
@@ -3925,6 +4050,11 @@ ${rewritten}`;
3925
4050
  if (!rewritten.includes("export default")) {
3926
4051
  rewritten += `
3927
4052
  export default ${componentClassName};
4053
+ `;
4054
+ }
4055
+ if (usesLegacyAnimations) {
4056
+ rewritten += `
4057
+ export const __ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ = true;
3928
4058
  `;
3929
4059
  }
3930
4060
  if (hmr) {
@@ -3953,6 +4083,7 @@ import "${hmrClientPath}";
3953
4083
  import '@angular/compiler';
3954
4084
  import { bootstrapApplication } from '@angular/platform-browser';
3955
4085
  import { provideClientHydration } from '@angular/platform-browser';
4086
+ import { withHttpTransferCacheOptions } from '@angular/platform-browser';
3956
4087
  import { provideZonelessChangeDetection } from '@angular/core';
3957
4088
  import * as pageModule from '${normalizedImportPath}';
3958
4089
 
@@ -3979,6 +4110,13 @@ var propProviders = Object.entries(pageProps).map(function(entry) {
3979
4110
  // that worked in SSR fail with NG0201 after hydration.
3980
4111
  var maybePageProviders = Reflect.get(pageModule, 'providers');
3981
4112
  var pageProviders = Array.isArray(maybePageProviders) ? maybePageProviders : [];
4113
+ var absoluteHttpTransferCacheOptions = {
4114
+ includePostRequests: false,
4115
+ includeRequestsWithAuthHeaders: false,
4116
+ filter: function(request) {
4117
+ return !request.headers.has('x-skip-transfer-cache');
4118
+ }
4119
+ };
3982
4120
 
3983
4121
  // Re-Bootstrap HMR with View Transitions API
3984
4122
  if (window.__ANGULAR_APP__) {
@@ -3994,7 +4132,7 @@ if (!document.querySelector(_sel)) {
3994
4132
 
3995
4133
  var providers = [provideZonelessChangeDetection()];
3996
4134
  if (!window.__HMR_SKIP_HYDRATION__ && !pageHasIslands) {
3997
- providers.push(provideClientHydration());
4135
+ providers.push(provideClientHydration(withHttpTransferCacheOptions(absoluteHttpTransferCacheOptions)));
3998
4136
  }
3999
4137
  delete window.__HMR_SKIP_HYDRATION__;
4000
4138
  providers.push.apply(providers, pageProviders);
@@ -4025,6 +4163,7 @@ if (pageHasRawStreamingSlots) {
4025
4163
  import '@angular/compiler';
4026
4164
  import { bootstrapApplication } from '@angular/platform-browser';
4027
4165
  import { provideClientHydration } from '@angular/platform-browser';
4166
+ import { withHttpTransferCacheOptions } from '@angular/platform-browser';
4028
4167
  import { enableProdMode, provideZonelessChangeDetection } from '@angular/core';
4029
4168
  import * as pageModule from '${normalizedImportPath}';
4030
4169
 
@@ -4051,12 +4190,19 @@ var propProviders = Object.entries(pageProps).map(function(entry) {
4051
4190
  // that worked in SSR fail with NG0201 after hydration.
4052
4191
  var maybePageProviders = Reflect.get(pageModule, 'providers');
4053
4192
  var pageProviders = Array.isArray(maybePageProviders) ? maybePageProviders : [];
4193
+ var absoluteHttpTransferCacheOptions = {
4194
+ includePostRequests: false,
4195
+ includeRequestsWithAuthHeaders: false,
4196
+ filter: function(request) {
4197
+ return !request.headers.has('x-skip-transfer-cache');
4198
+ }
4199
+ };
4054
4200
 
4055
4201
  enableProdMode();
4056
4202
 
4057
4203
  var providers = [provideZonelessChangeDetection()].concat(pageProviders).concat(propProviders);
4058
4204
  if (!pageHasIslands) {
4059
- providers.unshift(provideClientHydration());
4205
+ providers.unshift(provideClientHydration(withHttpTransferCacheOptions(absoluteHttpTransferCacheOptions)));
4060
4206
  }
4061
4207
  window.__ABS_SLOT_HYDRATION_PENDING__ = pageHasRawStreamingSlots;
4062
4208
 
@@ -4222,7 +4368,59 @@ var runWithStreamingSlotRegistry = async (task) => {
4222
4368
  };
4223
4369
  });
4224
4370
  };
4225
-
4371
+ // src/angular/deterministicEnv.ts
4372
+ import { InjectionToken } from "@angular/core";
4373
+ var DEFAULT_DETERMINISTIC_SEED = "absolute-angular";
4374
+ var DEFAULT_DETERMINISTIC_NOW = 0;
4375
+ var HASH_MULTIPLIER = 31;
4376
+ var FNV_OFFSET_BASIS = 2166136261;
4377
+ var FNV_PRIME = 16777619;
4378
+ var XORSHIFT_LEFT_1 = 13;
4379
+ var XORSHIFT_LEFT_2 = 5;
4380
+ var XORSHIFT_RIGHT = 17;
4381
+ var UINT32_MAX = 4294967296;
4382
+ var DETERMINISTIC_NOW = new InjectionToken("DETERMINISTIC_NOW");
4383
+ var DETERMINISTIC_RANDOM = new InjectionToken("DETERMINISTIC_RANDOM");
4384
+ var DETERMINISTIC_SEED = new InjectionToken("DETERMINISTIC_SEED");
4385
+ var hashSeed = (seed) => {
4386
+ const seedText = String(seed);
4387
+ let hash = FNV_OFFSET_BASIS;
4388
+ for (const char of seedText) {
4389
+ hash = Math.imul(hash ^ char.charCodeAt(0), FNV_PRIME);
4390
+ }
4391
+ return hash >>> 0 || HASH_MULTIPLIER;
4392
+ };
4393
+ var createDeterministicRandom = (seed = DEFAULT_DETERMINISTIC_SEED) => {
4394
+ let state = hashSeed(seed);
4395
+ return () => {
4396
+ state ^= state << XORSHIFT_LEFT_1;
4397
+ state ^= state >>> XORSHIFT_RIGHT;
4398
+ state ^= state << XORSHIFT_LEFT_2;
4399
+ return (state >>> 0) / UINT32_MAX;
4400
+ };
4401
+ };
4402
+ var normalizeNow = (now) => {
4403
+ if (now instanceof Date)
4404
+ return now.getTime();
4405
+ if (typeof now === "string")
4406
+ return new Date(now).getTime();
4407
+ if (typeof now === "number")
4408
+ return now;
4409
+ return DEFAULT_DETERMINISTIC_NOW;
4410
+ };
4411
+ var provideDeterministicEnv = (options = {}) => {
4412
+ const seed = String(options.seed ?? DEFAULT_DETERMINISTIC_SEED);
4413
+ const now = normalizeNow(options.now);
4414
+ return [
4415
+ { provide: DETERMINISTIC_SEED, useValue: seed },
4416
+ { provide: DETERMINISTIC_NOW, useValue: now },
4417
+ {
4418
+ deps: [DETERMINISTIC_SEED],
4419
+ provide: DETERMINISTIC_RANDOM,
4420
+ useFactory: createDeterministicRandom
4421
+ }
4422
+ ];
4423
+ };
4226
4424
  // src/angular/pageHandler.ts
4227
4425
  init_constants();
4228
4426
  import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
@@ -4716,6 +4914,79 @@ var renderFirstNotFound = async () => {
4716
4914
  init_registerClientScript();
4717
4915
  init_angularDeps();
4718
4916
 
4917
+ // src/angular/animationProviders.ts
4918
+ init_resolveAngularPackage();
4919
+ var noopAnimationProvidersPromise = null;
4920
+ var loadNoopAnimationProviders = async () => {
4921
+ const animations = await import(resolveAngularPackage("@angular/platform-browser/animations"));
4922
+ return animations.provideNoopAnimations();
4923
+ };
4924
+ var buildServerAnimationProviders = (usesLegacyAnimations) => {
4925
+ if (!usesLegacyAnimations)
4926
+ return Promise.resolve([]);
4927
+ noopAnimationProvidersPromise ??= loadNoopAnimationProviders();
4928
+ return noopAnimationProvidersPromise;
4929
+ };
4930
+
4931
+ // src/angular/routerRedirectProviders.ts
4932
+ init_resolveAngularPackage();
4933
+ var DEFAULT_REDIRECT_STATUS = 302;
4934
+ var SUCCESS_STATUS = 200;
4935
+ var isRouterRedirectCancel = (event, routerModule) => event instanceof routerModule.NavigationCancel && event.code === routerModule.NavigationCancellationCode.Redirect;
4936
+ var getNavigationStartUrl = (event, routerModule) => {
4937
+ if (!(event instanceof routerModule.NavigationStart))
4938
+ return null;
4939
+ return event.url;
4940
+ };
4941
+ var applyRedirectResponse = (responseInit, location) => {
4942
+ if (!responseInit)
4943
+ return;
4944
+ const headers = new Headers(responseInit.headers);
4945
+ headers.set("Location", location);
4946
+ responseInit.headers = headers;
4947
+ if (typeof responseInit.status === "undefined" || responseInit.status === SUCCESS_STATUS) {
4948
+ responseInit.status = DEFAULT_REDIRECT_STATUS;
4949
+ }
4950
+ };
4951
+ var buildRedirectEventHandler = (responseInit, routerModule) => {
4952
+ let waitingForRedirectTarget = false;
4953
+ return (event) => {
4954
+ if (isRouterRedirectCancel(event, routerModule)) {
4955
+ waitingForRedirectTarget = true;
4956
+ return;
4957
+ }
4958
+ if (!waitingForRedirectTarget)
4959
+ return;
4960
+ const redirectUrl = getNavigationStartUrl(event, routerModule);
4961
+ if (!redirectUrl)
4962
+ return;
4963
+ applyRedirectResponse(responseInit, redirectUrl);
4964
+ waitingForRedirectTarget = false;
4965
+ };
4966
+ };
4967
+ var buildRouterRedirectProviders = async (deps, responseInit) => {
4968
+ let routerModule;
4969
+ try {
4970
+ routerModule = await import(resolveAngularPackage("@angular/router"));
4971
+ } catch {
4972
+ return [];
4973
+ }
4974
+ return [
4975
+ {
4976
+ multi: true,
4977
+ provide: deps.ENVIRONMENT_INITIALIZER,
4978
+ useValue: () => {
4979
+ const router = deps.inject(routerModule.Router, {
4980
+ optional: true
4981
+ });
4982
+ if (!router)
4983
+ return;
4984
+ router.events.subscribe(buildRedirectEventHandler(responseInit, routerModule));
4985
+ }
4986
+ }
4987
+ ];
4988
+ };
4989
+
4719
4990
  // src/angular/lowerServerIslands.ts
4720
4991
  init_renderIslandMarkup();
4721
4992
  var ANGULAR_ISLAND_TAG_RE = /<absolute-island\b([^>]*)>[\s\S]*?<\/absolute-island>/gi;
@@ -4968,7 +5239,15 @@ init_ssrRender();
4968
5239
  var lastSelector = "angular-page";
4969
5240
  var isRecord5 = (value) => typeof value === "object" && value !== null;
4970
5241
  var isAngularComponent = (value) => typeof value === "function";
4971
- var resolvePageComponent = (pageModule) => {
5242
+ var resolvePageComponent = (pageModule, maybeProps) => {
5243
+ const factory = Reflect.get(pageModule, "factory");
5244
+ if (typeof factory === "function") {
5245
+ const factoryResult = factory(maybeProps);
5246
+ if (isAngularComponent(factoryResult)) {
5247
+ return factoryResult;
5248
+ }
5249
+ throw new Error("Angular page module factory must return an Angular component.");
5250
+ }
4972
5251
  if (isAngularComponent(pageModule.default)) {
4973
5252
  return pageModule.default;
4974
5253
  }
@@ -5015,6 +5294,28 @@ var resolveRuntimeAngularModulePath = async (pagePath) => {
5015
5294
  const expectedFileName = basename4(pagePath).replace(/\.ts$/, ".js");
5016
5295
  return outputs.find((output) => output.endsWith(`/${expectedFileName}`)) ?? outputs.find((output) => output.endsWith(`\\${expectedFileName}`)) ?? outputs[0] ?? pagePath;
5017
5296
  };
5297
+ var withHtmlContentType = (responseInit = {}) => {
5298
+ const headers = new Headers(responseInit.headers);
5299
+ if (!headers.has("Content-Type")) {
5300
+ headers.set("Content-Type", "text/html");
5301
+ }
5302
+ return { ...responseInit, headers };
5303
+ };
5304
+ var resolveRequestRenderUrl = (request) => {
5305
+ if (!request)
5306
+ return "/";
5307
+ try {
5308
+ const parsed = new URL(request.url);
5309
+ return `${parsed.pathname}${parsed.search}`;
5310
+ } catch {
5311
+ return "/";
5312
+ }
5313
+ };
5314
+ var assertNoHandlerProviders = (input) => {
5315
+ if (!("providers" in input))
5316
+ return;
5317
+ throw new Error("Angular handler providers are not supported. Export `providers` from the Angular page module, or inject REQUEST / REQUEST_CONTEXT for request-scoped data.");
5318
+ };
5018
5319
  var angularSsrContext = new AsyncLocalStorage3;
5019
5320
  setSsrContextGetter(() => angularSsrContext.getStore());
5020
5321
  var handleAngularPageRequest = async (input) => {
@@ -5026,17 +5327,8 @@ var handleAngularPageRequest = async (input) => {
5026
5327
  const options = input;
5027
5328
  const resolvedPagePath = input.pagePath;
5028
5329
  const maybeProps = input.props;
5029
- const userProviders = input.providers;
5030
- const resolvedUrl = (() => {
5031
- if (!input.request)
5032
- return "/";
5033
- try {
5034
- const parsed = new URL(input.request.url);
5035
- return `${parsed.pathname}${parsed.search}`;
5036
- } catch {
5037
- return "/";
5038
- }
5039
- })();
5330
+ const responseInit = input.responseInit ?? {};
5331
+ const resolvedUrl = resolveRequestRenderUrl(input.request);
5040
5332
  cacheRouteData(resolvedPagePath, {
5041
5333
  headTag: resolvedHeadTag,
5042
5334
  props: maybeProps
@@ -5050,6 +5342,7 @@ var handleAngularPageRequest = async (input) => {
5050
5342
  });
5051
5343
  }
5052
5344
  try {
5345
+ assertNoHandlerProviders(input);
5053
5346
  const handlerCallsite = options?.collectStreamingSlots === true ? undefined : getCurrentRouteRegistrationCallsite() ?? captureStreamingSlotWarningCallsite();
5054
5347
  const renderPageResponse = async () => {
5055
5348
  const baseDeps = await getAngularDeps();
@@ -5059,11 +5352,12 @@ var handleAngularPageRequest = async (input) => {
5059
5352
  if (!pageModule) {
5060
5353
  throw new Error(`Invalid Angular page module: ${resolvedPagePath}`);
5061
5354
  }
5062
- const PageComponent = resolvePageComponent(pageModule);
5355
+ const PageComponent = resolvePageComponent(pageModule, maybeProps);
5063
5356
  if (!isAngularComponent(PageComponent)) {
5064
5357
  throw new Error(`Angular page module must export an Angular component: ${resolvedPagePath}`);
5065
5358
  }
5066
5359
  const hasIslands = typeof pageModule.__ABSOLUTE_PAGE_HAS_ISLANDS__ === "boolean" ? pageModule.__ABSOLUTE_PAGE_HAS_ISLANDS__ : false;
5360
+ const usesLegacyAnimations = pageModule.__ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ === true;
5067
5361
  const ssrResult = await loadSsrDeps(runtimePagePath);
5068
5362
  const deps = buildDeps(ssrResult, baseDeps);
5069
5363
  const tokenMap = discoverTokens(pageModule);
@@ -5073,14 +5367,19 @@ var handleAngularPageRequest = async (input) => {
5073
5367
  if (ssrResult?.core)
5074
5368
  resetSsrSanitizer();
5075
5369
  const sanitizer = getSsrSanitizer(deps);
5076
- const providers = buildProviders(deps, sanitizer, maybeProps, tokenMap, userProviders);
5370
+ const pageProvidersExport = Reflect.get(pageModule, "providers");
5371
+ const pageProviders = Array.isArray(pageProvidersExport) ? pageProvidersExport : [];
5372
+ const combinedProviders = [
5373
+ ...await buildRouterRedirectProviders(deps, responseInit),
5374
+ ...pageProviders,
5375
+ ...await buildServerAnimationProviders(usesLegacyAnimations)
5376
+ ];
5377
+ const providers = buildProviders(deps, sanitizer, maybeProps, tokenMap, input.request, input.requestContext, responseInit, combinedProviders);
5077
5378
  const rawHtml = await renderAngularApp(deps, PageComponent, providers, htmlString, resolvedUrl);
5078
5379
  const shouldProcessIslands = hasIslands || rawHtml.includes("<absolute-island");
5079
5380
  const htmlWithLoweredIslands = shouldProcessIslands ? await lowerAngularServerIslands(rawHtml) : rawHtml;
5080
5381
  const html = injectIslandPageContext(injectSsrScripts(htmlWithLoweredIslands, requestId, resolvedIndexPath, maybeProps), { hasIslands: shouldProcessIslands });
5081
- return new Response(html, {
5082
- headers: { "Content-Type": "text/html" }
5083
- });
5382
+ return new Response(html, withHtmlContentType(responseInit));
5084
5383
  };
5085
5384
  return runWithStreamingSlotWarningScope(() => options?.collectStreamingSlots === true ? withRegisteredStreamingSlots(renderPageResponse, options) : renderPageResponse(), { handlerCallsite });
5086
5385
  } catch (error) {
@@ -5096,9 +5395,33 @@ var handleAngularPageRequest = async (input) => {
5096
5395
  }
5097
5396
  });
5098
5397
  };
5398
+ // src/angular/pendingTask.ts
5399
+ import { inject, PendingTasks } from "@angular/core";
5400
+ var withPendingTask = async (work) => {
5401
+ const removeTask = inject(PendingTasks).add();
5402
+ try {
5403
+ return await work();
5404
+ } finally {
5405
+ removeTask();
5406
+ }
5407
+ };
5408
+
5409
+ // src/angular/server.ts
5410
+ init_requestProviders();
5099
5411
  export {
5100
- handleAngularPageRequest
5412
+ withPendingTask,
5413
+ provideDeterministicEnv,
5414
+ handleAngularPageRequest,
5415
+ createDeterministicRandom,
5416
+ buildAbsoluteHttpTransferCacheOptions,
5417
+ RESPONSE_INIT,
5418
+ REQUEST_CONTEXT,
5419
+ REQUEST,
5420
+ DETERMINISTIC_SEED,
5421
+ DETERMINISTIC_RANDOM,
5422
+ DETERMINISTIC_NOW,
5423
+ ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER
5101
5424
  };
5102
5425
 
5103
- //# debugId=A711B02EC18980AE64756E2164756E21
5426
+ //# debugId=6D90F2DC4CE8B00D64756E2164756E21
5104
5427
  //# sourceMappingURL=server.js.map