@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
 
@@ -13163,6 +13309,59 @@ var runWithStreamingSlotRegistry = async (task) => {
13163
13309
  // src/angular/index.ts
13164
13310
  import"@angular/compiler";
13165
13311
 
13312
+ // src/angular/deterministicEnv.ts
13313
+ import { InjectionToken } from "@angular/core";
13314
+ var DEFAULT_DETERMINISTIC_SEED = "absolute-angular";
13315
+ var DEFAULT_DETERMINISTIC_NOW = 0;
13316
+ var HASH_MULTIPLIER = 31;
13317
+ var FNV_OFFSET_BASIS = 2166136261;
13318
+ var FNV_PRIME = 16777619;
13319
+ var XORSHIFT_LEFT_1 = 13;
13320
+ var XORSHIFT_LEFT_2 = 5;
13321
+ var XORSHIFT_RIGHT = 17;
13322
+ var UINT32_MAX = 4294967296;
13323
+ var DETERMINISTIC_NOW = new InjectionToken("DETERMINISTIC_NOW");
13324
+ var DETERMINISTIC_RANDOM = new InjectionToken("DETERMINISTIC_RANDOM");
13325
+ var DETERMINISTIC_SEED = new InjectionToken("DETERMINISTIC_SEED");
13326
+ var hashSeed = (seed) => {
13327
+ const seedText = String(seed);
13328
+ let hash = FNV_OFFSET_BASIS;
13329
+ for (const char of seedText) {
13330
+ hash = Math.imul(hash ^ char.charCodeAt(0), FNV_PRIME);
13331
+ }
13332
+ return hash >>> 0 || HASH_MULTIPLIER;
13333
+ };
13334
+ var createDeterministicRandom = (seed = DEFAULT_DETERMINISTIC_SEED) => {
13335
+ let state = hashSeed(seed);
13336
+ return () => {
13337
+ state ^= state << XORSHIFT_LEFT_1;
13338
+ state ^= state >>> XORSHIFT_RIGHT;
13339
+ state ^= state << XORSHIFT_LEFT_2;
13340
+ return (state >>> 0) / UINT32_MAX;
13341
+ };
13342
+ };
13343
+ var normalizeNow = (now) => {
13344
+ if (now instanceof Date)
13345
+ return now.getTime();
13346
+ if (typeof now === "string")
13347
+ return new Date(now).getTime();
13348
+ if (typeof now === "number")
13349
+ return now;
13350
+ return DEFAULT_DETERMINISTIC_NOW;
13351
+ };
13352
+ var provideDeterministicEnv = (options = {}) => {
13353
+ const seed = String(options.seed ?? DEFAULT_DETERMINISTIC_SEED);
13354
+ const now = normalizeNow(options.now);
13355
+ return [
13356
+ { provide: DETERMINISTIC_SEED, useValue: seed },
13357
+ { provide: DETERMINISTIC_NOW, useValue: now },
13358
+ {
13359
+ deps: [DETERMINISTIC_SEED],
13360
+ provide: DETERMINISTIC_RANDOM,
13361
+ useFactory: createDeterministicRandom
13362
+ }
13363
+ ];
13364
+ };
13166
13365
  // src/angular/pageHandler.ts
13167
13366
  init_constants();
13168
13367
  import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
@@ -13656,6 +13855,79 @@ var renderFirstNotFound = async () => {
13656
13855
  init_registerClientScript();
13657
13856
  init_angularDeps();
13658
13857
 
13858
+ // src/angular/animationProviders.ts
13859
+ init_resolveAngularPackage();
13860
+ var noopAnimationProvidersPromise = null;
13861
+ var loadNoopAnimationProviders = async () => {
13862
+ const animations = await import(resolveAngularPackage("@angular/platform-browser/animations"));
13863
+ return animations.provideNoopAnimations();
13864
+ };
13865
+ var buildServerAnimationProviders = (usesLegacyAnimations) => {
13866
+ if (!usesLegacyAnimations)
13867
+ return Promise.resolve([]);
13868
+ noopAnimationProvidersPromise ??= loadNoopAnimationProviders();
13869
+ return noopAnimationProvidersPromise;
13870
+ };
13871
+
13872
+ // src/angular/routerRedirectProviders.ts
13873
+ init_resolveAngularPackage();
13874
+ var DEFAULT_REDIRECT_STATUS = 302;
13875
+ var SUCCESS_STATUS = 200;
13876
+ var isRouterRedirectCancel = (event, routerModule) => event instanceof routerModule.NavigationCancel && event.code === routerModule.NavigationCancellationCode.Redirect;
13877
+ var getNavigationStartUrl = (event, routerModule) => {
13878
+ if (!(event instanceof routerModule.NavigationStart))
13879
+ return null;
13880
+ return event.url;
13881
+ };
13882
+ var applyRedirectResponse = (responseInit, location) => {
13883
+ if (!responseInit)
13884
+ return;
13885
+ const headers = new Headers(responseInit.headers);
13886
+ headers.set("Location", location);
13887
+ responseInit.headers = headers;
13888
+ if (typeof responseInit.status === "undefined" || responseInit.status === SUCCESS_STATUS) {
13889
+ responseInit.status = DEFAULT_REDIRECT_STATUS;
13890
+ }
13891
+ };
13892
+ var buildRedirectEventHandler = (responseInit, routerModule) => {
13893
+ let waitingForRedirectTarget = false;
13894
+ return (event) => {
13895
+ if (isRouterRedirectCancel(event, routerModule)) {
13896
+ waitingForRedirectTarget = true;
13897
+ return;
13898
+ }
13899
+ if (!waitingForRedirectTarget)
13900
+ return;
13901
+ const redirectUrl = getNavigationStartUrl(event, routerModule);
13902
+ if (!redirectUrl)
13903
+ return;
13904
+ applyRedirectResponse(responseInit, redirectUrl);
13905
+ waitingForRedirectTarget = false;
13906
+ };
13907
+ };
13908
+ var buildRouterRedirectProviders = async (deps, responseInit) => {
13909
+ let routerModule;
13910
+ try {
13911
+ routerModule = await import(resolveAngularPackage("@angular/router"));
13912
+ } catch {
13913
+ return [];
13914
+ }
13915
+ return [
13916
+ {
13917
+ multi: true,
13918
+ provide: deps.ENVIRONMENT_INITIALIZER,
13919
+ useValue: () => {
13920
+ const router = deps.inject(routerModule.Router, {
13921
+ optional: true
13922
+ });
13923
+ if (!router)
13924
+ return;
13925
+ router.events.subscribe(buildRedirectEventHandler(responseInit, routerModule));
13926
+ }
13927
+ }
13928
+ ];
13929
+ };
13930
+
13659
13931
  // src/angular/lowerServerIslands.ts
13660
13932
  init_renderIslandMarkup();
13661
13933
  var ANGULAR_ISLAND_TAG_RE = /<absolute-island\b([^>]*)>[\s\S]*?<\/absolute-island>/gi;
@@ -13908,7 +14180,15 @@ init_ssrRender();
13908
14180
  var lastSelector = "angular-page";
13909
14181
  var isRecord5 = (value) => typeof value === "object" && value !== null;
13910
14182
  var isAngularComponent = (value) => typeof value === "function";
13911
- var resolvePageComponent = (pageModule) => {
14183
+ var resolvePageComponent = (pageModule, maybeProps) => {
14184
+ const factory = Reflect.get(pageModule, "factory");
14185
+ if (typeof factory === "function") {
14186
+ const factoryResult = factory(maybeProps);
14187
+ if (isAngularComponent(factoryResult)) {
14188
+ return factoryResult;
14189
+ }
14190
+ throw new Error("Angular page module factory must return an Angular component.");
14191
+ }
13912
14192
  if (isAngularComponent(pageModule.default)) {
13913
14193
  return pageModule.default;
13914
14194
  }
@@ -13955,6 +14235,28 @@ var resolveRuntimeAngularModulePath = async (pagePath) => {
13955
14235
  const expectedFileName = basename4(pagePath).replace(/\.ts$/, ".js");
13956
14236
  return outputs.find((output) => output.endsWith(`/${expectedFileName}`)) ?? outputs.find((output) => output.endsWith(`\\${expectedFileName}`)) ?? outputs[0] ?? pagePath;
13957
14237
  };
14238
+ var withHtmlContentType = (responseInit = {}) => {
14239
+ const headers = new Headers(responseInit.headers);
14240
+ if (!headers.has("Content-Type")) {
14241
+ headers.set("Content-Type", "text/html");
14242
+ }
14243
+ return { ...responseInit, headers };
14244
+ };
14245
+ var resolveRequestRenderUrl = (request) => {
14246
+ if (!request)
14247
+ return "/";
14248
+ try {
14249
+ const parsed = new URL(request.url);
14250
+ return `${parsed.pathname}${parsed.search}`;
14251
+ } catch {
14252
+ return "/";
14253
+ }
14254
+ };
14255
+ var assertNoHandlerProviders = (input) => {
14256
+ if (!("providers" in input))
14257
+ return;
14258
+ 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.");
14259
+ };
13958
14260
  var angularSsrContext = new AsyncLocalStorage3;
13959
14261
  setSsrContextGetter(() => angularSsrContext.getStore());
13960
14262
  var handleAngularPageRequest = async (input) => {
@@ -13966,17 +14268,8 @@ var handleAngularPageRequest = async (input) => {
13966
14268
  const options = input;
13967
14269
  const resolvedPagePath = input.pagePath;
13968
14270
  const maybeProps = input.props;
13969
- const userProviders = input.providers;
13970
- const resolvedUrl = (() => {
13971
- if (!input.request)
13972
- return "/";
13973
- try {
13974
- const parsed = new URL(input.request.url);
13975
- return `${parsed.pathname}${parsed.search}`;
13976
- } catch {
13977
- return "/";
13978
- }
13979
- })();
14271
+ const responseInit = input.responseInit ?? {};
14272
+ const resolvedUrl = resolveRequestRenderUrl(input.request);
13980
14273
  cacheRouteData(resolvedPagePath, {
13981
14274
  headTag: resolvedHeadTag,
13982
14275
  props: maybeProps
@@ -13990,6 +14283,7 @@ var handleAngularPageRequest = async (input) => {
13990
14283
  });
13991
14284
  }
13992
14285
  try {
14286
+ assertNoHandlerProviders(input);
13993
14287
  const handlerCallsite = options?.collectStreamingSlots === true ? undefined : getCurrentRouteRegistrationCallsite() ?? captureStreamingSlotWarningCallsite();
13994
14288
  const renderPageResponse = async () => {
13995
14289
  const baseDeps = await getAngularDeps();
@@ -13999,11 +14293,12 @@ var handleAngularPageRequest = async (input) => {
13999
14293
  if (!pageModule) {
14000
14294
  throw new Error(`Invalid Angular page module: ${resolvedPagePath}`);
14001
14295
  }
14002
- const PageComponent = resolvePageComponent(pageModule);
14296
+ const PageComponent = resolvePageComponent(pageModule, maybeProps);
14003
14297
  if (!isAngularComponent(PageComponent)) {
14004
14298
  throw new Error(`Angular page module must export an Angular component: ${resolvedPagePath}`);
14005
14299
  }
14006
14300
  const hasIslands = typeof pageModule.__ABSOLUTE_PAGE_HAS_ISLANDS__ === "boolean" ? pageModule.__ABSOLUTE_PAGE_HAS_ISLANDS__ : false;
14301
+ const usesLegacyAnimations = pageModule.__ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ === true;
14007
14302
  const ssrResult = await loadSsrDeps(runtimePagePath);
14008
14303
  const deps = buildDeps(ssrResult, baseDeps);
14009
14304
  const tokenMap = discoverTokens(pageModule);
@@ -14013,14 +14308,19 @@ var handleAngularPageRequest = async (input) => {
14013
14308
  if (ssrResult?.core)
14014
14309
  resetSsrSanitizer();
14015
14310
  const sanitizer = getSsrSanitizer(deps);
14016
- const providers = buildProviders(deps, sanitizer, maybeProps, tokenMap, userProviders);
14311
+ const pageProvidersExport = Reflect.get(pageModule, "providers");
14312
+ const pageProviders = Array.isArray(pageProvidersExport) ? pageProvidersExport : [];
14313
+ const combinedProviders = [
14314
+ ...await buildRouterRedirectProviders(deps, responseInit),
14315
+ ...pageProviders,
14316
+ ...await buildServerAnimationProviders(usesLegacyAnimations)
14317
+ ];
14318
+ const providers = buildProviders(deps, sanitizer, maybeProps, tokenMap, input.request, input.requestContext, responseInit, combinedProviders);
14017
14319
  const rawHtml = await renderAngularApp(deps, PageComponent, providers, htmlString, resolvedUrl);
14018
14320
  const shouldProcessIslands = hasIslands || rawHtml.includes("<absolute-island");
14019
14321
  const htmlWithLoweredIslands = shouldProcessIslands ? await lowerAngularServerIslands(rawHtml) : rawHtml;
14020
14322
  const html = injectIslandPageContext(injectSsrScripts(htmlWithLoweredIslands, requestId, resolvedIndexPath, maybeProps), { hasIslands: shouldProcessIslands });
14021
- return new Response(html, {
14022
- headers: { "Content-Type": "text/html" }
14023
- });
14323
+ return new Response(html, withHtmlContentType(responseInit));
14024
14324
  };
14025
14325
  return runWithStreamingSlotWarningScope(() => options?.collectStreamingSlots === true ? withRegisteredStreamingSlots(renderPageResponse, options) : renderPageResponse(), { handlerCallsite });
14026
14326
  } catch (error) {
@@ -14036,6 +14336,20 @@ var handleAngularPageRequest = async (input) => {
14036
14336
  }
14037
14337
  });
14038
14338
  };
14339
+ // src/angular/pendingTask.ts
14340
+ import { inject, PendingTasks } from "@angular/core";
14341
+ var withPendingTask = async (work) => {
14342
+ const removeTask = inject(PendingTasks).add();
14343
+ try {
14344
+ return await work();
14345
+ } finally {
14346
+ removeTask();
14347
+ }
14348
+ };
14349
+
14350
+ // src/angular/index.ts
14351
+ init_requestProviders();
14352
+
14039
14353
  // src/angular/createIsland.ts
14040
14354
  init_renderIslandMarkup();
14041
14355
  var createTypedIsland = (registry) => (props) => renderIslandMarkup(registry, props);
@@ -14230,7 +14544,7 @@ import {
14230
14544
  Component as Component2,
14231
14545
  Input as Input2,
14232
14546
  NgZone,
14233
- inject,
14547
+ inject as inject2,
14234
14548
  signal
14235
14549
  } from "@angular/core";
14236
14550
  import { DomSanitizer } from "@angular/platform-browser";
@@ -14247,9 +14561,9 @@ class StreamSlotComponent {
14247
14561
  constructor() {
14248
14562
  this.fallbackHtml = "";
14249
14563
  }
14250
- cdr = inject(ChangeDetectorRef);
14251
- sanitizer = inject(DomSanitizer);
14252
- zone = inject(NgZone);
14564
+ cdr = inject2(ChangeDetectorRef);
14565
+ sanitizer = inject2(DomSanitizer);
14566
+ zone = inject2(NgZone);
14253
14567
  slotConsumer = (payload) => {
14254
14568
  this.zone.run(() => {
14255
14569
  this.currentHtml.set(this.sanitizer.bypassSecurityTrustHtml(resolvePayloadHtml(payload)));
@@ -14335,14 +14649,25 @@ StreamSlotComponent = __legacyDecorateClassTS([
14335
14649
  })
14336
14650
  ], StreamSlotComponent);
14337
14651
  export {
14652
+ withPendingTask,
14338
14653
  renderIsland,
14654
+ provideDeterministicEnv,
14339
14655
  handleAngularPageRequest,
14340
14656
  getCachedRouteData,
14341
14657
  createTypedIsland,
14658
+ createDeterministicRandom,
14659
+ buildAbsoluteHttpTransferCacheOptions,
14342
14660
  StreamSlotComponent,
14661
+ RESPONSE_INIT,
14662
+ REQUEST_CONTEXT,
14663
+ REQUEST,
14343
14664
  IslandStore,
14344
- Island
14665
+ Island,
14666
+ DETERMINISTIC_SEED,
14667
+ DETERMINISTIC_RANDOM,
14668
+ DETERMINISTIC_NOW,
14669
+ ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER
14345
14670
  };
14346
14671
 
14347
- //# debugId=278C518DD69255CE64756E2164756E21
14672
+ //# debugId=07C2F03EB5A746E764756E2164756E21
14348
14673
  //# sourceMappingURL=index.js.map