mage-obsidian 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/cli/buildThemes.d.ts +3 -0
  2. package/dist/cli/buildThemes.d.ts.map +1 -0
  3. package/{src/cli/buildThemes.ts → dist/cli/buildThemes.js} +77 -121
  4. package/dist/cli/buildThemes.js.map +1 -0
  5. package/dist/config/default.d.ts +16 -0
  6. package/dist/config/default.d.ts.map +1 -0
  7. package/{src/config/default.ts → dist/config/default.js} +2 -11
  8. package/dist/config/default.js.map +1 -0
  9. package/dist/core/configResolver.d.ts +38 -0
  10. package/dist/core/configResolver.d.ts.map +1 -0
  11. package/{src/core/configResolver.ts → dist/core/configResolver.js} +21 -60
  12. package/dist/core/configResolver.js.map +1 -0
  13. package/dist/core/contractValidator.d.ts +16 -0
  14. package/dist/core/contractValidator.d.ts.map +1 -0
  15. package/{src/core/contractValidator.ts → dist/core/contractValidator.js} +3 -10
  16. package/dist/core/contractValidator.js.map +1 -0
  17. package/dist/core/cssResolver.d.ts +5 -0
  18. package/dist/core/cssResolver.d.ts.map +1 -0
  19. package/{src/core/cssResolver.ts → dist/core/cssResolver.js} +26 -53
  20. package/dist/core/cssResolver.js.map +1 -0
  21. package/dist/core/generateInterceptors.d.ts +10 -0
  22. package/dist/core/generateInterceptors.d.ts.map +1 -0
  23. package/{src/core/generateInterceptors.ts → dist/core/generateInterceptors.js} +55 -109
  24. package/dist/core/generateInterceptors.js.map +1 -0
  25. package/dist/core/generateJsconfig.d.ts +45 -0
  26. package/dist/core/generateJsconfig.d.ts.map +1 -0
  27. package/{src/core/generateJsconfig.ts → dist/core/generateJsconfig.js} +32 -55
  28. package/dist/core/generateJsconfig.js.map +1 -0
  29. package/dist/core/moduleResolver.d.ts +22 -0
  30. package/dist/core/moduleResolver.d.ts.map +1 -0
  31. package/{src/core/moduleResolver.ts → dist/core/moduleResolver.js} +28 -62
  32. package/dist/core/moduleResolver.js.map +1 -0
  33. package/dist/core/preCompileFiles.d.ts +6 -0
  34. package/dist/core/preCompileFiles.d.ts.map +1 -0
  35. package/{src/core/preCompileFiles.ts → dist/core/preCompileFiles.js} +22 -48
  36. package/dist/core/preCompileFiles.js.map +1 -0
  37. package/dist/core/preCompileMagentoFiles.d.ts +3 -0
  38. package/dist/core/preCompileMagentoFiles.d.ts.map +1 -0
  39. package/{src/core/preCompileMagentoFiles.ts → dist/core/preCompileMagentoFiles.js} +4 -10
  40. package/dist/core/preCompileMagentoFiles.js.map +1 -0
  41. package/dist/core/themeResolverSync.d.ts +6 -0
  42. package/dist/core/themeResolverSync.d.ts.map +1 -0
  43. package/{src/core/themeResolverSync.ts → dist/core/themeResolverSync.js} +25 -26
  44. package/dist/core/themeResolverSync.js.map +1 -0
  45. package/dist/runtime/i18nCore.d.ts +71 -0
  46. package/dist/runtime/i18nCore.d.ts.map +1 -0
  47. package/{src/runtime/i18nCore.ts → dist/runtime/i18nCore.js} +47 -49
  48. package/dist/runtime/i18nCore.js.map +1 -0
  49. package/dist/runtime/interceptorManager.d.ts +45 -0
  50. package/dist/runtime/interceptorManager.d.ts.map +1 -0
  51. package/{src/runtime/interceptorManager.ts → dist/runtime/interceptorManager.js} +14 -72
  52. package/dist/runtime/interceptorManager.js.map +1 -0
  53. package/dist/runtime/islands.d.ts +45 -0
  54. package/dist/runtime/islands.d.ts.map +1 -0
  55. package/{src/runtime/islands.ts → dist/runtime/islands.js} +5 -30
  56. package/dist/runtime/islands.js.map +1 -0
  57. package/dist/runtime/sectionStoreCore.d.ts +108 -0
  58. package/dist/runtime/sectionStoreCore.d.ts.map +1 -0
  59. package/{src/runtime/sectionStoreCore.ts → dist/runtime/sectionStoreCore.js} +23 -93
  60. package/dist/runtime/sectionStoreCore.js.map +1 -0
  61. package/dist/utils/findComponents.d.ts +17 -0
  62. package/dist/utils/findComponents.d.ts.map +1 -0
  63. package/dist/utils/findComponents.js +66 -0
  64. package/dist/utils/findComponents.js.map +1 -0
  65. package/dist/utils/runWithConcurrency.d.ts +10 -0
  66. package/dist/utils/runWithConcurrency.d.ts.map +1 -0
  67. package/{src/utils/runWithConcurrency.ts → dist/utils/runWithConcurrency.js} +3 -9
  68. package/dist/utils/runWithConcurrency.js.map +1 -0
  69. package/dist/vite/defaultNodeResolver.d.ts +9 -0
  70. package/dist/vite/defaultNodeResolver.d.ts.map +1 -0
  71. package/{src/vite/defaultNodeResolver.ts → dist/vite/defaultNodeResolver.js} +3 -1
  72. package/dist/vite/defaultNodeResolver.js.map +1 -0
  73. package/dist/vite/inheritAssetsModuleResolver.d.ts +8 -0
  74. package/dist/vite/inheritAssetsModuleResolver.d.ts.map +1 -0
  75. package/{src/vite/inheritAssetsModuleResolver.ts → dist/vite/inheritAssetsModuleResolver.js} +6 -20
  76. package/dist/vite/inheritAssetsModuleResolver.js.map +1 -0
  77. package/dist/vite/inheritModuleResolver.d.ts +8 -0
  78. package/dist/vite/inheritModuleResolver.d.ts.map +1 -0
  79. package/{src/vite/inheritModuleResolver.ts → dist/vite/inheritModuleResolver.js} +4 -9
  80. package/dist/vite/inheritModuleResolver.js.map +1 -0
  81. package/dist/vite/interceptorsPlugin.d.ts +10 -0
  82. package/dist/vite/interceptorsPlugin.d.ts.map +1 -0
  83. package/{src/vite/interceptorsPlugin.ts → dist/vite/interceptorsPlugin.js} +12 -29
  84. package/dist/vite/interceptorsPlugin.js.map +1 -0
  85. package/dist/vite/magentoHrmRewrite.d.ts +6 -0
  86. package/dist/vite/magentoHrmRewrite.d.ts.map +1 -0
  87. package/{src/vite/magentoHrmRewrite.ts → dist/vite/magentoHrmRewrite.js} +16 -15
  88. package/dist/vite/magentoHrmRewrite.js.map +1 -0
  89. package/dist/vite/sharedPlugins.d.ts +35 -0
  90. package/dist/vite/sharedPlugins.d.ts.map +1 -0
  91. package/{src/vite/sharedPlugins.ts → dist/vite/sharedPlugins.js} +7 -9
  92. package/dist/vite/sharedPlugins.js.map +1 -0
  93. package/dist/vite/themeSourceWatcher.d.ts +16 -0
  94. package/dist/vite/themeSourceWatcher.d.ts.map +1 -0
  95. package/{src/vite/themeSourceWatcher.ts → dist/vite/themeSourceWatcher.js} +19 -24
  96. package/dist/vite/themeSourceWatcher.js.map +1 -0
  97. package/dist/vite/unresolvedModuleGuard.d.ts +17 -0
  98. package/dist/vite/unresolvedModuleGuard.d.ts.map +1 -0
  99. package/{src/vite/unresolvedModuleGuard.ts → dist/vite/unresolvedModuleGuard.js} +27 -27
  100. package/dist/vite/unresolvedModuleGuard.js.map +1 -0
  101. package/package.json +60 -10
  102. package/.github/workflows/ci.yml +0 -38
  103. package/.github/workflows/publish.yml +0 -36
  104. package/.oxlintrc.json +0 -19
  105. package/.prettierignore +0 -7
  106. package/.prettierrc.json +0 -7
  107. package/eslint.config.js +0 -24
  108. package/pnpm-workspace.yaml +0 -4
  109. package/src/utils/findComponents.ts +0 -83
  110. package/tsconfig.json +0 -34
  111. package/vitest.config.js +0 -18
  112. /package/{src → dist}/config/eslint.js +0 -0
  113. /package/{src → dist}/templates/base_main_js_file.js +0 -0
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Framework island runtime — the browser side of `renderVueComponent`.
3
+ *
4
+ * PHP emits an inert marker per component
5
+ * (`<div data-mage-island data-component data-props data-strategy>`); this
6
+ * module turns each marker into a mounted Vue app. Every island is its own app
7
+ * (preserving isolation), but the Vue runtime and the i18n plugin are loaded
8
+ * once per page and shared, and "visible" islands hydrate only when they enter
9
+ * the viewport — so below-the-fold components cost nothing until scrolled to.
10
+ *
11
+ * All side effects (dynamic import, app creation, plugin wiring, viewport
12
+ * observation) are injected, so the discovery/hydration logic is unit-testable
13
+ * in Node without a DOM, a bundler, or Vue. The concrete wiring lives in the
14
+ * module's `web/js/islands.js`.
15
+ */
16
+ interface IslandElement {
17
+ dataset: Record<string, string | undefined>;
18
+ }
19
+ interface AppLike {
20
+ mount(el: unknown): unknown;
21
+ }
22
+ interface HydrateDeps {
23
+ importComponent(source: string): Promise<{
24
+ default?: unknown;
25
+ }>;
26
+ createApp(component: unknown, props?: Record<string, unknown>): AppLike;
27
+ configureApp(app: AppLike): void;
28
+ }
29
+ interface DiscoverDeps extends HydrateDeps {
30
+ observe(element: IslandElement, onVisible: () => void): void;
31
+ }
32
+ /**
33
+ * Mount a single island. Idempotent: the first call claims the element and
34
+ * later calls return immediately, so re-observation never double-mounts.
35
+ *
36
+ * @throws Error When the marker has no `data-component`.
37
+ */
38
+ export declare function hydrateIsland(element: IslandElement, deps: HydrateDeps): Promise<AppLike | undefined>;
39
+ /**
40
+ * Hydrate every marker. `eager` markers mount now; the rest mount when the
41
+ * injected observer reports them visible.
42
+ */
43
+ export declare function hydrateAll(elements: Iterable<IslandElement>, deps: DiscoverDeps): void;
44
+ export {};
45
+ //# sourceMappingURL=islands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"islands.d.ts","sourceRoot":"","sources":["../../src/runtime/islands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,UAAU,aAAa;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC/C;AAED,UAAU,OAAO;IACb,KAAK,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC;CAC/B;AAED,UAAU,WAAW;IACjB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAChE,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;IACxE,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;CACpC;AAED,UAAU,YAAa,SAAQ,WAAW;IACtC,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAChE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAC/B,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,WAAW,GAClB,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAmB9B;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAWtF"}
@@ -13,72 +13,47 @@
13
13
  * in Node without a DOM, a bundler, or Vue. The concrete wiring lives in the
14
14
  * module's `web/js/islands.js`.
15
15
  */
16
-
17
16
  // Set synchronously before the async import so a second observer callback for
18
17
  // the same element is a no-op (dataset key for `data-mage-island-mounted`).
19
18
  const MOUNTED_FLAG = "mageIslandMounted";
20
-
21
- interface IslandElement {
22
- dataset: Record<string, string | undefined>;
23
- }
24
-
25
- interface AppLike {
26
- mount(el: unknown): unknown;
27
- }
28
-
29
- interface HydrateDeps {
30
- importComponent(source: string): Promise<{ default?: unknown }>;
31
- createApp(component: unknown, props?: Record<string, unknown>): AppLike;
32
- configureApp(app: AppLike): void;
33
- }
34
-
35
- interface DiscoverDeps extends HydrateDeps {
36
- observe(element: IslandElement, onVisible: () => void): void;
37
- }
38
-
39
19
  /**
40
20
  * Mount a single island. Idempotent: the first call claims the element and
41
21
  * later calls return immediately, so re-observation never double-mounts.
42
22
  *
43
23
  * @throws Error When the marker has no `data-component`.
44
24
  */
45
- export async function hydrateIsland(
46
- element: IslandElement,
47
- deps: HydrateDeps,
48
- ): Promise<AppLike | undefined> {
25
+ export async function hydrateIsland(element, deps) {
49
26
  if (element.dataset[MOUNTED_FLAG]) {
50
27
  return undefined;
51
28
  }
52
29
  element.dataset[MOUNTED_FLAG] = "1";
53
-
54
30
  const source = element.dataset.component;
55
31
  if (!source) {
56
32
  throw new Error("Island marker is missing data-component.");
57
33
  }
58
-
59
34
  const module = await deps.importComponent(source);
60
35
  const component = module.default ?? module;
61
36
  const props = element.dataset.props ? JSON.parse(element.dataset.props) : {};
62
-
63
37
  const app = deps.createApp(component, props);
64
38
  deps.configureApp(app);
65
39
  app.mount(element);
66
40
  return app;
67
41
  }
68
-
69
42
  /**
70
43
  * Hydrate every marker. `eager` markers mount now; the rest mount when the
71
44
  * injected observer reports them visible.
72
45
  */
73
- export function hydrateAll(elements: Iterable<IslandElement>, deps: DiscoverDeps): void {
46
+ export function hydrateAll(elements, deps) {
74
47
  for (const element of elements) {
75
48
  const strategy = element.dataset.strategy ?? "visible";
76
49
  if (strategy === "eager") {
77
50
  void hydrateIsland(element, deps);
78
- } else {
51
+ }
52
+ else {
79
53
  deps.observe(element, () => {
80
54
  void hydrateIsland(element, deps);
81
55
  });
82
56
  }
83
57
  }
84
58
  }
59
+ //# sourceMappingURL=islands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"islands.js","sourceRoot":"","sources":["../../src/runtime/islands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,8EAA8E;AAC9E,4EAA4E;AAC5E,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAoBzC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAC/B,OAAsB,EACtB,IAAiB;IAEjB,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC;IAEpC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;IACzC,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC;IAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE7E,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC7C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IACvB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnB,OAAO,GAAG,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,QAAiC,EAAE,IAAkB;IAC5E,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,SAAS,CAAC;QACvD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACvB,KAAK,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE;gBACvB,KAAK,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;QACP,CAAC;IACL,CAAC;AACL,CAAC"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Section store core — pure helpers for mirroring a set of server-pushed,
3
+ * versioned "sections" into a reactive store backed by localStorage.
4
+ *
5
+ * This is the GENERIC mechanism, deliberately domain-agnostic: it knows how to
6
+ * parse/merge/select sections, decide staleness, read a version cookie and
7
+ * decide when to hydrate — but nothing about WHICH endpoint, cookie or storage
8
+ * key a given integration uses. A binding (e.g. the Magento customer-data
9
+ * adapter) supplies those and wraps these primitives with Vue/Pinia reactivity.
10
+ *
11
+ * Kept free of Vue, Pinia and the DOM so the parsing/merge/staleness rules are
12
+ * unit-testable in isolation.
13
+ */
14
+ export type SectionData = Record<string, unknown>;
15
+ export type SectionMap = Record<string, SectionData>;
16
+ export interface SectionLoadOptions {
17
+ baseUrl?: string;
18
+ forceNewTimestamp?: boolean;
19
+ }
20
+ export interface SectionRuntimeConfig {
21
+ lifetimeSeconds: number;
22
+ expirableSections: string[];
23
+ }
24
+ interface SectionRuntimeScope {
25
+ __MAGE_OBSIDIAN_SECTIONS__?: {
26
+ lifetime?: unknown;
27
+ expirable?: unknown;
28
+ };
29
+ }
30
+ declare global {
31
+ interface Window {
32
+ __MAGE_OBSIDIAN_SECTIONS__?: {
33
+ lifetime?: unknown;
34
+ expirable?: unknown;
35
+ };
36
+ }
37
+ }
38
+ /**
39
+ * Parse the raw section-storage JSON into a map of section objects. Tolerates
40
+ * missing/corrupt input and drops non-object section values so the caller
41
+ * always gets a clean `{ [section]: object }` map.
42
+ */
43
+ export declare function parseSectionStorage(raw: string | null | undefined): SectionMap;
44
+ /**
45
+ * Return a single section, or null when it is absent or not an object.
46
+ */
47
+ export declare function selectSection(sections: SectionMap | null | undefined, name: string): SectionData | null;
48
+ /**
49
+ * Overlay freshly loaded sections onto the current map (a section-load response
50
+ * merges per section; non-object values are ignored).
51
+ */
52
+ export declare function mergeSections(current: SectionMap | null | undefined, incoming: SectionMap | null | undefined): SectionMap;
53
+ /**
54
+ * Whether a section should be (re)fetched. A missing section is stale; a
55
+ * section without a positive `data_id` is a client-side section that never
56
+ * expires; with no positive lifetime nothing expires either. Otherwise it is
57
+ * stale once `data_id + lifetime` has passed.
58
+ */
59
+ export declare function isSectionStale(section: SectionData | null | undefined, lifetimeSeconds: number, nowSeconds: number): boolean;
60
+ /**
61
+ * Build the section-load URL a binding uses to (re)load sections. `endpoint` is
62
+ * supplied by the binding (this core is endpoint-agnostic). An empty name list
63
+ * requests ALL sections by omitting the `sections` param — Magento's protocol
64
+ * returns every section then and rejects a literal `sections=*` with 400.
65
+ */
66
+ export declare function buildSectionLoadUrl(endpoint: string, sectionNames: string[], options?: SectionLoadOptions): string;
67
+ /**
68
+ * Read a single cookie value from a `document.cookie` string. Returns "" when
69
+ * the cookie is absent. Kept pure (the binding passes `document.cookie` in) so
70
+ * the version lookup is testable without a DOM.
71
+ */
72
+ export declare function readCookie(cookieString: string | null | undefined, name: string): string;
73
+ /**
74
+ * Whether the store must hydrate sections from the server on init.
75
+ *
76
+ * A binding bumps a version (e.g. Magento's `private_content_version` cookie)
77
+ * whenever the server's pushed content changes. When nothing is cached yet, or
78
+ * the current version has moved past the last synced version, the cached
79
+ * sections are stale.
80
+ */
81
+ export declare function needsHydration(sections: SectionMap | null | undefined, syncedVersion: string, currentVersion: string): boolean;
82
+ /**
83
+ * True when the session marker cookie is gone. Magento's login/logout controllers
84
+ * delete it server-side, so its absence means cached sections are stale (the
85
+ * version cookie doesn't move on logout). False when no marker is configured.
86
+ */
87
+ export declare function sessionInvalidated(cookieString: string | null | undefined, sessionCookieName: string): boolean;
88
+ /**
89
+ * The expirable sections that have aged out and must be re-fetched, mirroring the
90
+ * lifetime branch of Magento's native `getExpiredSectionNames`: a section listed
91
+ * in `expirableNames` expires once `data_id + lifetimeSeconds <= now`.
92
+ *
93
+ * This is the backstop the version cookie cannot provide: `private_content_version`
94
+ * only moves on POST, so a section whose server data changed through a non-POST
95
+ * path the browser took — most commonly the PHP session/quote expiring while
96
+ * localStorage lives on — is otherwise never re-fetched, leaving a stale snapshot
97
+ * (e.g. a cart badge that outlives its quote). Absent sections are skipped here,
98
+ * exactly like native (they reload via the version/empty-cache path instead).
99
+ */
100
+ export declare function expiredSectionNames(sections: SectionMap | null | undefined, lifetimeSeconds: number, expirableNames: string[], nowSeconds: number): string[];
101
+ /**
102
+ * Read the runtime section config a binding's host page publishes (lifetime +
103
+ * which sections expire by lifetime). Kept pure — the binding passes the scope
104
+ * (e.g. `window`) — so it is testable without a DOM, like `readI18nConfig`.
105
+ */
106
+ export declare function readSectionRuntimeConfig(scope?: SectionRuntimeScope | undefined): SectionRuntimeConfig;
107
+ export {};
108
+ //# sourceMappingURL=sectionStoreCore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sectionStoreCore.d.ts","sourceRoot":"","sources":["../../src/runtime/sectionStoreCore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAClD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAErD,MAAM,WAAW,kBAAkB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,UAAU,mBAAmB;IACzB,0BAA0B,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC5E;AAGD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,0BAA0B,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;YAAC,SAAS,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;KAC5E;CACJ;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,CAa9E;AAED;;GAEG;AACH,wBAAgB,aAAa,CACzB,QAAQ,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EACvC,IAAI,EAAE,MAAM,GACb,WAAW,GAAG,IAAI,CAQpB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CACzB,OAAO,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EACtC,QAAQ,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,GACxC,UAAU,CAEZ;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC1B,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EACvC,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,MAAM,GACnB,OAAO,CAcT;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAC/B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,GAAE,kBAAuB,GACjC,MAAM,CAaR;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAcxF;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC1B,QAAQ,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EACvC,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,GACvB,OAAO,CAKT;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACvC,iBAAiB,EAAE,MAAM,GAC1B,OAAO,CAKT;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAC/B,QAAQ,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EACvC,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EAAE,EACxB,UAAU,EAAE,MAAM,GACnB,MAAM,EAAE,CAiBV;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACpC,KAAK,GAAE,mBAAmB,GAAG,SAA8D,GAC5F,oBAAoB,CAUtB"}
@@ -11,93 +11,53 @@
11
11
  * Kept free of Vue, Pinia and the DOM so the parsing/merge/staleness rules are
12
12
  * unit-testable in isolation.
13
13
  */
14
-
15
- export type SectionData = Record<string, unknown>;
16
- export type SectionMap = Record<string, SectionData>;
17
-
18
- export interface SectionLoadOptions {
19
- baseUrl?: string;
20
- forceNewTimestamp?: boolean;
21
- }
22
-
23
- export interface SectionRuntimeConfig {
24
- lifetimeSeconds: number;
25
- expirableSections: string[];
26
- }
27
-
28
- interface SectionRuntimeScope {
29
- __MAGE_OBSIDIAN_SECTIONS__?: { lifetime?: unknown; expirable?: unknown };
30
- }
31
-
32
- // Published by PHP on the page before the ESM runtime loads.
33
- declare global {
34
- interface Window {
35
- __MAGE_OBSIDIAN_SECTIONS__?: { lifetime?: unknown; expirable?: unknown };
36
- }
37
- }
38
-
39
14
  /**
40
15
  * Parse the raw section-storage JSON into a map of section objects. Tolerates
41
16
  * missing/corrupt input and drops non-object section values so the caller
42
17
  * always gets a clean `{ [section]: object }` map.
43
18
  */
44
- export function parseSectionStorage(raw: string | null | undefined): SectionMap {
19
+ export function parseSectionStorage(raw) {
45
20
  if (typeof raw !== "string" || raw === "") {
46
21
  return {};
47
22
  }
48
-
49
- let parsed: unknown;
23
+ let parsed;
50
24
  try {
51
25
  parsed = JSON.parse(raw);
52
- } catch {
26
+ }
27
+ catch {
53
28
  return {};
54
29
  }
55
-
56
30
  return pickObjectEntries(parsed);
57
31
  }
58
-
59
32
  /**
60
33
  * Return a single section, or null when it is absent or not an object.
61
34
  */
62
- export function selectSection(
63
- sections: SectionMap | null | undefined,
64
- name: string,
65
- ): SectionData | null {
35
+ export function selectSection(sections, name) {
66
36
  if (!sections || typeof sections !== "object") {
67
37
  return null;
68
38
  }
69
39
  const value = sections[name];
70
40
  return value && typeof value === "object" && !Array.isArray(value)
71
- ? (value as SectionData)
41
+ ? value
72
42
  : null;
73
43
  }
74
-
75
44
  /**
76
45
  * Overlay freshly loaded sections onto the current map (a section-load response
77
46
  * merges per section; non-object values are ignored).
78
47
  */
79
- export function mergeSections(
80
- current: SectionMap | null | undefined,
81
- incoming: SectionMap | null | undefined,
82
- ): SectionMap {
48
+ export function mergeSections(current, incoming) {
83
49
  return { ...pickObjectEntries(current), ...pickObjectEntries(incoming) };
84
50
  }
85
-
86
51
  /**
87
52
  * Whether a section should be (re)fetched. A missing section is stale; a
88
53
  * section without a positive `data_id` is a client-side section that never
89
54
  * expires; with no positive lifetime nothing expires either. Otherwise it is
90
55
  * stale once `data_id + lifetime` has passed.
91
56
  */
92
- export function isSectionStale(
93
- section: SectionData | null | undefined,
94
- lifetimeSeconds: number,
95
- nowSeconds: number,
96
- ): boolean {
57
+ export function isSectionStale(section, lifetimeSeconds, nowSeconds) {
97
58
  if (!section || typeof section !== "object") {
98
59
  return true;
99
60
  }
100
-
101
61
  const dataId = Number(section.data_id);
102
62
  if (!Number.isFinite(dataId) || dataId <= 0) {
103
63
  return false;
@@ -105,41 +65,32 @@ export function isSectionStale(
105
65
  if (!Number.isFinite(lifetimeSeconds) || lifetimeSeconds <= 0) {
106
66
  return false;
107
67
  }
108
-
109
68
  return dataId + lifetimeSeconds <= nowSeconds;
110
69
  }
111
-
112
70
  /**
113
71
  * Build the section-load URL a binding uses to (re)load sections. `endpoint` is
114
72
  * supplied by the binding (this core is endpoint-agnostic). An empty name list
115
73
  * requests ALL sections by omitting the `sections` param — Magento's protocol
116
74
  * returns every section then and rejects a literal `sections=*` with 400.
117
75
  */
118
- export function buildSectionLoadUrl(
119
- endpoint: string,
120
- sectionNames: string[],
121
- options: SectionLoadOptions = {},
122
- ): string {
76
+ export function buildSectionLoadUrl(endpoint, sectionNames, options = {}) {
123
77
  const { baseUrl = "/", forceNewTimestamp = false } = options;
124
78
  const names = Array.isArray(sectionNames) ? sectionNames.filter(Boolean) : [];
125
79
  const base = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
126
80
  const path = endpoint.startsWith("/") ? endpoint.slice(1) : endpoint;
127
-
128
- const params: string[] = [];
81
+ const params = [];
129
82
  if (names.length) {
130
83
  params.push(`sections=${names.join(",")}`);
131
84
  }
132
85
  params.push(`force_new_section_timestamp=${forceNewTimestamp ? "true" : "false"}`);
133
-
134
86
  return `${base}${path}?${params.join("&")}`;
135
87
  }
136
-
137
88
  /**
138
89
  * Read a single cookie value from a `document.cookie` string. Returns "" when
139
90
  * the cookie is absent. Kept pure (the binding passes `document.cookie` in) so
140
91
  * the version lookup is testable without a DOM.
141
92
  */
142
- export function readCookie(cookieString: string | null | undefined, name: string): string {
93
+ export function readCookie(cookieString, name) {
143
94
  if (typeof cookieString !== "string" || cookieString === "" || !name) {
144
95
  return "";
145
96
  }
@@ -154,7 +105,6 @@ export function readCookie(cookieString: string | null | undefined, name: string
154
105
  }
155
106
  return "";
156
107
  }
157
-
158
108
  /**
159
109
  * Whether the store must hydrate sections from the server on init.
160
110
  *
@@ -163,32 +113,23 @@ export function readCookie(cookieString: string | null | undefined, name: string
163
113
  * the current version has moved past the last synced version, the cached
164
114
  * sections are stale.
165
115
  */
166
- export function needsHydration(
167
- sections: SectionMap | null | undefined,
168
- syncedVersion: string,
169
- currentVersion: string,
170
- ): boolean {
116
+ export function needsHydration(sections, syncedVersion, currentVersion) {
171
117
  if (!sections || typeof sections !== "object" || Object.keys(sections).length === 0) {
172
118
  return true;
173
119
  }
174
120
  return currentVersion !== "" && currentVersion !== syncedVersion;
175
121
  }
176
-
177
122
  /**
178
123
  * True when the session marker cookie is gone. Magento's login/logout controllers
179
124
  * delete it server-side, so its absence means cached sections are stale (the
180
125
  * version cookie doesn't move on logout). False when no marker is configured.
181
126
  */
182
- export function sessionInvalidated(
183
- cookieString: string | null | undefined,
184
- sessionCookieName: string,
185
- ): boolean {
127
+ export function sessionInvalidated(cookieString, sessionCookieName) {
186
128
  if (!sessionCookieName) {
187
129
  return false;
188
130
  }
189
131
  return readCookie(cookieString, sessionCookieName) === "";
190
132
  }
191
-
192
133
  /**
193
134
  * The expirable sections that have aged out and must be re-fetched, mirroring the
194
135
  * lifetime branch of Magento's native `getExpiredSectionNames`: a section listed
@@ -201,59 +142,48 @@ export function sessionInvalidated(
201
142
  * (e.g. a cart badge that outlives its quote). Absent sections are skipped here,
202
143
  * exactly like native (they reload via the version/empty-cache path instead).
203
144
  */
204
- export function expiredSectionNames(
205
- sections: SectionMap | null | undefined,
206
- lifetimeSeconds: number,
207
- expirableNames: string[],
208
- nowSeconds: number,
209
- ): string[] {
145
+ export function expiredSectionNames(sections, lifetimeSeconds, expirableNames, nowSeconds) {
210
146
  if (!Array.isArray(expirableNames) || expirableNames.length === 0) {
211
147
  return [];
212
148
  }
213
149
  const map = sections && typeof sections === "object" ? sections : {};
214
- const expired: string[] = [];
150
+ const expired = [];
215
151
  for (const name of expirableNames) {
216
152
  const section = map[name];
217
- if (
218
- section &&
153
+ if (section &&
219
154
  typeof section === "object" &&
220
- isSectionStale(section, lifetimeSeconds, nowSeconds)
221
- ) {
155
+ isSectionStale(section, lifetimeSeconds, nowSeconds)) {
222
156
  expired.push(name);
223
157
  }
224
158
  }
225
159
  return expired;
226
160
  }
227
-
228
161
  /**
229
162
  * Read the runtime section config a binding's host page publishes (lifetime +
230
163
  * which sections expire by lifetime). Kept pure — the binding passes the scope
231
164
  * (e.g. `window`) — so it is testable without a DOM, like `readI18nConfig`.
232
165
  */
233
- export function readSectionRuntimeConfig(
234
- scope: SectionRuntimeScope | undefined = typeof window !== "undefined" ? window : undefined,
235
- ): SectionRuntimeConfig {
166
+ export function readSectionRuntimeConfig(scope = typeof window !== "undefined" ? window : undefined) {
236
167
  const config = scope && scope.__MAGE_OBSIDIAN_SECTIONS__;
237
168
  const lifetime = Number(config && config.lifetime);
238
169
  const expirable = config && config.expirable;
239
170
  return {
240
171
  lifetimeSeconds: Number.isFinite(lifetime) && lifetime > 0 ? lifetime : 0,
241
172
  expirableSections: Array.isArray(expirable)
242
- ? expirable.filter((name): name is string => typeof name === "string")
173
+ ? expirable.filter((name) => typeof name === "string")
243
174
  : [],
244
175
  };
245
176
  }
246
-
247
- function pickObjectEntries(value: unknown): SectionMap {
177
+ function pickObjectEntries(value) {
248
178
  if (!value || typeof value !== "object" || Array.isArray(value)) {
249
179
  return {};
250
180
  }
251
-
252
- const result: SectionMap = {};
181
+ const result = {};
253
182
  for (const [key, entry] of Object.entries(value)) {
254
183
  if (entry && typeof entry === "object" && !Array.isArray(entry)) {
255
- result[key] = entry as SectionData;
184
+ result[key] = entry;
256
185
  }
257
186
  }
258
187
  return result;
259
188
  }
189
+ //# sourceMappingURL=sectionStoreCore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sectionStoreCore.js","sourceRoot":"","sources":["../../src/runtime/sectionStoreCore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Recursively searches a module's source folders for component files — matched by
3
+ * the extensions each folder declares (`directory.ext`) — and organizes them into
4
+ * an object.
5
+ *
6
+ * @param {string} moduleName - The name of the module to associate the files with.
7
+ * @param moduleDir
8
+ * @param directories
9
+ * @returns {Promise<Object>} - A promise that resolves to an object where:
10
+ * - The keys are unique identifiers for the files, formed by combining
11
+ * subdirectories and file names (e.g., `Vendor_ModuleName/FilePath`).
12
+ * - The values are the full relative paths to the files within the `components` folder.
13
+ * @throws {Error} - Throws an error if duplicate file names (with different extensions) are found.
14
+ */
15
+ declare function getFilesFromFolders(moduleName: any, moduleDir: any, directories: any): Promise<any[]>;
16
+ export default getFilesFromFolders;
17
+ //# sourceMappingURL=findComponents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findComponents.d.ts","sourceRoot":"","sources":["../../src/utils/findComponents.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AACH,iBAAe,mBAAmB,CAAC,UAAU,KAAA,EAAE,SAAS,KAAA,EAAE,WAAW,KAAA,kBA+DpE;AAED,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,66 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ /**
4
+ * Recursively searches a module's source folders for component files — matched by
5
+ * the extensions each folder declares (`directory.ext`) — and organizes them into
6
+ * an object.
7
+ *
8
+ * @param {string} moduleName - The name of the module to associate the files with.
9
+ * @param moduleDir
10
+ * @param directories
11
+ * @returns {Promise<Object>} - A promise that resolves to an object where:
12
+ * - The keys are unique identifiers for the files, formed by combining
13
+ * subdirectories and file names (e.g., `Vendor_ModuleName/FilePath`).
14
+ * - The values are the full relative paths to the files within the `components` folder.
15
+ * @throws {Error} - Throws an error if duplicate file names (with different extensions) are found.
16
+ */
17
+ async function getFilesFromFolders(moduleName, moduleDir, directories) {
18
+ const componentsDir = path.resolve(moduleDir);
19
+ // oxlint-disable-next-line only-used-in-recursion
20
+ const getFilesFromFolderWithExt = async (dir, folderToSearch, extArr, baseDir = "") => {
21
+ // console.log(moduleName, dir, folderToSearch, extArr, baseDir = "");
22
+ if (!fs.existsSync(dir))
23
+ return [];
24
+ const entries = await fs.promises.readdir(dir, { withFileTypes: true });
25
+ const keyRegistered = [];
26
+ const files = await Promise.all(entries.map(async (entry) => {
27
+ const fullPath = path.join(dir, entry.name);
28
+ const relativePath = path.join(baseDir, entry.name);
29
+ if (entry.isDirectory()) {
30
+ return await getFilesFromFolderWithExt(fullPath, folderToSearch, extArr, relativePath);
31
+ }
32
+ else if (entry.isFile() &&
33
+ extArr.some((ext) => entry.name.endsWith(`.${ext}`)) &&
34
+ // Skip co-located unit tests/specs so test-only deps
35
+ // (e.g. @vue/test-utils) never leak into the build.
36
+ !/\.(test|spec)\.[jt]sx?$/.test(entry.name)) {
37
+ const fileName = path.parse(entry.name).name;
38
+ let key = baseDir === "" ? fileName : `${baseDir}/${fileName}`;
39
+ key = `${moduleName}/${folderToSearch}/${key}`;
40
+ const filePath = path.join(dir, entry.name);
41
+ if (keyRegistered.includes(key)) {
42
+ throw new Error(`Duplicate file names detected: The file "${filePath}".`);
43
+ }
44
+ keyRegistered.push(key);
45
+ return { [key]: filePath };
46
+ }
47
+ return null;
48
+ }));
49
+ return files.filter(Boolean).flat();
50
+ };
51
+ try {
52
+ let result = [];
53
+ for (const directory of directories) {
54
+ const folderPath = path.resolve(componentsDir, directory.src);
55
+ const filesArray = await getFilesFromFolderWithExt(folderPath, directory.src, directory.ext);
56
+ result.push(...filesArray);
57
+ }
58
+ result = result.reduce((acc, item) => Object.assign(acc, item), {});
59
+ return result;
60
+ }
61
+ catch (err) {
62
+ throw new Error(`Error while processing JavaScript or Vue files in the components folder of module "${moduleName}": ${err.message}`, { cause: err });
63
+ }
64
+ }
65
+ export default getFilesFromFolders;
66
+ //# sourceMappingURL=findComponents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findComponents.js","sourceRoot":"","sources":["../../src/utils/findComponents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Run async workers over a list of items with a bounded number running at once.
3
+ *
4
+ * Results are returned in the same order as `items` regardless of completion
5
+ * order. The first rejection aborts the run (no new workers are started) and is
6
+ * propagated, mirroring Promise.all semantics. `limit` defaults to the number of
7
+ * items.
8
+ */
9
+ export default function runWithConcurrency<T, R>(items: T[], worker: (item: T, index: number) => Promise<R>, limit?: number): Promise<R[]>;
10
+ //# sourceMappingURL=runWithConcurrency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runWithConcurrency.d.ts","sourceRoot":"","sources":["../../src/utils/runWithConcurrency.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAA8B,kBAAkB,CAAC,CAAC,EAAE,CAAC,EACjD,KAAK,EAAE,CAAC,EAAE,EACV,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9C,KAAK,GAAE,MAAqB,GAC7B,OAAO,CAAC,CAAC,EAAE,CAAC,CAsBd"}