@reidelsaltres/pureper 0.2.15 → 0.2.18

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 (40) hide show
  1. package/out/foundation/Fetcher.d.ts.map +1 -1
  2. package/out/foundation/Fetcher.js +8 -13
  3. package/out/foundation/Fetcher.js.map +1 -1
  4. package/out/foundation/Injection.d.ts +87 -0
  5. package/out/foundation/Injection.d.ts.map +1 -0
  6. package/out/foundation/Injection.js +149 -0
  7. package/out/foundation/Injection.js.map +1 -0
  8. package/out/foundation/Triplet.d.ts +30 -25
  9. package/out/foundation/Triplet.d.ts.map +1 -1
  10. package/out/foundation/Triplet.js +96 -115
  11. package/out/foundation/Triplet.js.map +1 -1
  12. package/out/foundation/TripletDecorator.d.ts +11 -0
  13. package/out/foundation/TripletDecorator.d.ts.map +1 -1
  14. package/out/foundation/TripletDecorator.js +25 -8
  15. package/out/foundation/TripletDecorator.js.map +1 -1
  16. package/out/foundation/component_api/UniHtml.d.ts +5 -1
  17. package/out/foundation/component_api/UniHtml.d.ts.map +1 -1
  18. package/out/foundation/component_api/UniHtml.js +23 -5
  19. package/out/foundation/component_api/UniHtml.js.map +1 -1
  20. package/out/foundation/worker/ServiceWorker.d.ts +48 -17
  21. package/out/foundation/worker/ServiceWorker.d.ts.map +1 -1
  22. package/out/foundation/worker/ServiceWorker.js +186 -119
  23. package/out/foundation/worker/ServiceWorker.js.map +1 -1
  24. package/out/index.d.ts +4 -3
  25. package/out/index.d.ts.map +1 -1
  26. package/out/index.js +3 -2
  27. package/out/index.js.map +1 -1
  28. package/package.json +1 -1
  29. package/src/foundation/Fetcher.ts +9 -14
  30. package/src/foundation/Injection.ts +183 -0
  31. package/src/foundation/Triplet.ts +114 -141
  32. package/src/foundation/TripletDecorator.ts +32 -8
  33. package/src/foundation/component_api/UniHtml.ts +26 -5
  34. package/src/foundation/worker/ServiceWorker.ts +203 -129
  35. package/src/foundation/worker/serviceworker.js +191 -0
  36. package/src/index.ts +8 -5
  37. package/out/foundation/worker/serviceworker.d.ts +0 -1
  38. package/out/foundation/worker/serviceworker.d.ts.map +0 -1
  39. package/out/foundation/worker/serviceworker.js +0 -2
  40. package/out/foundation/worker/serviceworker.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Fetcher.d.ts","sourceRoot":"","sources":["../../src/foundation/Fetcher.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,OAAO,OAAO,OAAO;WACX,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAqBvC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;WAoBnC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;mBAiBxB,aAAa;CAOrC"}
1
+ {"version":3,"file":"Fetcher.d.ts","sourceRoot":"","sources":["../../src/foundation/Fetcher.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,OAAO,OAAO,OAAO;WACX,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAgBvC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;WAgBnC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;mBAiBxB,aAAa;CAarC"}
@@ -1,40 +1,29 @@
1
1
  import { HOSTING_ORIGIN } from "./Hosting.js";
2
- // cache stores response bodies (text) by resolved URL so we can reuse them safely
3
- const temporaryCache = new Map();
4
2
  // keep in-flight promises to deduplicate concurrent identical requests
5
3
  const inFlightText = new Map();
6
4
  const inFlightJSON = new Map();
7
5
  export default class Fetcher {
8
6
  static async fetchText(url) {
9
7
  const resolved = this.resolveUrl(url);
10
- if (temporaryCache.has(resolved))
11
- return temporaryCache.get(resolved);
12
8
  // If a request for the same URL is already in-flight, reuse its promise
13
9
  if (inFlightText.has(resolved))
14
10
  return inFlightText.get(resolved);
15
11
  const p = (async () => {
16
12
  const response = await this.internalFetch(resolved);
17
- const text = await response.text();
18
- temporaryCache.set(resolved, text);
19
- return text;
13
+ return response.text();
20
14
  })();
21
15
  inFlightText.set(resolved, p);
22
- // cleanup entry when finished
23
16
  p.finally(() => inFlightText.delete(resolved));
24
17
  return p;
25
18
  }
26
19
  static async fetchJSON(url) {
27
20
  const resolved = this.resolveUrl(url);
28
- if (temporaryCache.has(resolved))
29
- return JSON.parse(temporaryCache.get(resolved));
30
21
  // If a request for the same URL is already in-flight, reuse its promise
31
22
  if (inFlightJSON.has(resolved))
32
23
  return inFlightJSON.get(resolved);
33
24
  const p = (async () => {
34
25
  const response = await this.internalFetch(resolved);
35
- const json = await response.json();
36
- temporaryCache.set(resolved, JSON.stringify(json));
37
- return json;
26
+ return response.json();
38
27
  })();
39
28
  inFlightJSON.set(resolved, p);
40
29
  p.finally(() => inFlightJSON.delete(resolved));
@@ -56,6 +45,12 @@ export default class Fetcher {
56
45
  return new URL(trimmed, `${HOSTING_ORIGIN}/`).href;
57
46
  }
58
47
  static async internalFetch(resolvedUrl) {
48
+ // L2: check ServiceWorker CacheStorage before hitting the network
49
+ if ('caches' in window) {
50
+ const cached = await caches.match(resolvedUrl);
51
+ if (cached)
52
+ return cached;
53
+ }
59
54
  const response = await fetch(resolvedUrl, { cache: 'default' });
60
55
  if (!response.ok) {
61
56
  throw new Error(`HTTP error! ${resolvedUrl} status: ${response.status}`);
@@ -1 +1 @@
1
- {"version":3,"file":"Fetcher.js","sourceRoot":"","sources":["../../src/foundation/Fetcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Fetcher.js","sourceRoot":"","sources":["../../src/foundation/Fetcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,uEAAuE;AACvE,MAAM,YAAY,GAAiC,IAAI,GAAG,EAAE,CAAC;AAC7D,MAAM,YAAY,GAA8B,IAAI,GAAG,EAAE,CAAC;AAC1D,MAAM,CAAC,OAAO,OAAO,OAAO;IACxB,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,GAAW;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAEtC,wEAAwE;QACxE,IAAI,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC;QAEnE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;YAClB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YACpD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC,CAAC,EAAE,CAAC;QAEL,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC9B,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAE/C,OAAO,CAAC,CAAC;IACb,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,GAAW;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAEtC,wEAAwE;QACxE,IAAI,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC;QAEnE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;YAClB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YACpD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC,CAAC,EAAE,CAAC;QAEL,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC9B,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,CAAC;IACb,CAAC;IAEM,MAAM,CAAC,UAAU,CAAC,GAAW;QAChC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QAE3B,mEAAmE;QACnE,IAAI,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,OAAO,CAAC;QAE9D,wBAAwB;QACxB,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,OAAO,EAAE,CAAC;QAE7E,4FAA4F;QAC5F,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,cAAc,GAAG,OAAO,EAAE,CAAC;QAElE,+CAA+C;QAC/C,+GAA+G;QAC/G,OAAO,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC;IACvD,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,WAAmB;QAClD,kEAAkE;QAClE,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC/C,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAC;QAC9B,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,eAAe,WAAW,YAAY,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,QAAQ,CAAC;IACpB,CAAC;CACJ"}
@@ -0,0 +1,87 @@
1
+ import Observable from "./api/Observer.js";
2
+ import { AnyConstructor } from "./component_api/mixin/Proto.js";
3
+ import UniHtml from "./component_api/UniHtml.js";
4
+ export type ImplementationStruct = {
5
+ markupURL?: string;
6
+ markup?: string;
7
+ cssURL?: string;
8
+ css?: string;
9
+ ltCssURL?: string;
10
+ ltCss?: string;
11
+ class?: AnyConstructor<UniHtml>;
12
+ };
13
+ /**
14
+ * Implementation — a swappable variant for a Triplet placeholder.
15
+ *
16
+ * Each placeholder (component tag or page route) can have multiple registered
17
+ * implementations. One is active at a time; switching triggers a reload on
18
+ * all live instances.
19
+ *
20
+ * ```ts
21
+ * // Register the default implementation
22
+ * @ReComponent({ markupURL: './Button.hmle', cssURL: './Button.css' }, "re-button")
23
+ * class ReButton extends Component { ... }
24
+ *
25
+ * // Register an alternative implementation
26
+ * @ReImplementation({ markupURL: './FancyButton.hmle', cssURL: './FancyButton.css' }, "re-button")
27
+ * class FancyButton extends Component { ... }
28
+ *
29
+ * // Switch all re-button instances to FancyButton
30
+ * Placeholder.switchTo("re-button", "FancyButton");
31
+ *
32
+ * // Switch a single instance manually
33
+ * const btn = document.querySelector("re-button");
34
+ * Placeholder.switchInstance(btn, "FancyButton");
35
+ * ```
36
+ */
37
+ export declare class Implementation {
38
+ readonly name: string;
39
+ readonly markup?: Promise<string>;
40
+ readonly style?: Promise<string>;
41
+ readonly globalStyle?: Promise<string>;
42
+ readonly uniClass?: AnyConstructor<UniHtml>;
43
+ constructor(name: string, struct: ImplementationStruct);
44
+ }
45
+ /**
46
+ * Placeholder — manages a named slot (tag or route) with swappable implementations.
47
+ *
48
+ * - `Placeholder.get(name)` — get or create a placeholder
49
+ * - `placeholder.addImplementation(impl)` — register an implementation
50
+ * - `Placeholder.switchTo(name, implName)` — globally switch + reload all instances
51
+ * - `Placeholder.switchInstance(instance, implName)` — switch one instance
52
+ */
53
+ export declare class Placeholder {
54
+ /** Все зарегистрированные placeholders по имени (tag / route). */
55
+ private static readonly _all;
56
+ readonly name: string;
57
+ readonly implementations: Map<string, Implementation>;
58
+ readonly activeImpl: Observable<Implementation | null>;
59
+ /** Все живые экземпляры этого placeholder для reload при смене implementation. */
60
+ private readonly _instances;
61
+ private constructor();
62
+ /** Get or create a placeholder by name. */
63
+ static get(name: string): Placeholder;
64
+ /** Check if a placeholder exists. */
65
+ static has(name: string): boolean;
66
+ /** Add an implementation. The first one added becomes active by default. */
67
+ addImplementation(impl: Implementation): void;
68
+ /** Get the currently active implementation. */
69
+ getActive(): Implementation | null;
70
+ /** Track a live instance for reload. */
71
+ trackInstance(instance: UniHtml): void;
72
+ /** Untrack a disposed instance. */
73
+ untrackInstance(instance: UniHtml): void;
74
+ /** Get all tracked live instances. */
75
+ getInstances(): Set<UniHtml>;
76
+ /**
77
+ * Switch the active implementation globally.
78
+ * All live instances of this placeholder will reload.
79
+ */
80
+ static switchTo(placeholderName: string, implName: string): Promise<void>;
81
+ /**
82
+ * Switch a single instance to a different implementation and reload it.
83
+ * Does NOT change the global active implementation.
84
+ */
85
+ static switchInstance(placeholderName: string, instance: UniHtml, implName: string): Promise<void>;
86
+ }
87
+ //# sourceMappingURL=Injection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Injection.d.ts","sourceRoot":"","sources":["../../src/foundation/Injection.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,OAAO,MAAM,4BAA4B,CAAC;AAEjD,MAAM,MAAM,oBAAoB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,KAAK,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;CACnC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,cAAc;IACvB,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,SAAgB,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,SAAgB,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,SAAgB,QAAQ,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;gBAEhC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB;CAiBhE;AAED;;;;;;;GAOG;AACH,qBAAa,WAAW;IACpB,kEAAkE;IAClE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAuC;IAEnE,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAa;IACzE,SAAgB,UAAU,EAAE,UAAU,CAAC,cAAc,GAAG,IAAI,CAAC,CAAwB;IAErF,kFAAkF;IAClF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA2B;IAEtD,OAAO;IAIP,2CAA2C;WAC7B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IAS5C,qCAAqC;WACvB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIxC,4EAA4E;IACrE,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAcpD,+CAA+C;IACxC,SAAS,IAAI,cAAc,GAAG,IAAI;IAIzC,wCAAwC;IACjC,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAI7C,mCAAmC;IAC5B,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAI/C,sCAAsC;IAC/B,YAAY,IAAI,GAAG,CAAC,OAAO,CAAC;IAInC;;;OAGG;WACiB,QAAQ,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBtF;;;OAGG;WACiB,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWlH"}
@@ -0,0 +1,149 @@
1
+ import Observable from "./api/Observer.js";
2
+ import Fetcher from "./Fetcher.js";
3
+ /**
4
+ * Implementation — a swappable variant for a Triplet placeholder.
5
+ *
6
+ * Each placeholder (component tag or page route) can have multiple registered
7
+ * implementations. One is active at a time; switching triggers a reload on
8
+ * all live instances.
9
+ *
10
+ * ```ts
11
+ * // Register the default implementation
12
+ * @ReComponent({ markupURL: './Button.hmle', cssURL: './Button.css' }, "re-button")
13
+ * class ReButton extends Component { ... }
14
+ *
15
+ * // Register an alternative implementation
16
+ * @ReImplementation({ markupURL: './FancyButton.hmle', cssURL: './FancyButton.css' }, "re-button")
17
+ * class FancyButton extends Component { ... }
18
+ *
19
+ * // Switch all re-button instances to FancyButton
20
+ * Placeholder.switchTo("re-button", "FancyButton");
21
+ *
22
+ * // Switch a single instance manually
23
+ * const btn = document.querySelector("re-button");
24
+ * Placeholder.switchInstance(btn, "FancyButton");
25
+ * ```
26
+ */
27
+ export class Implementation {
28
+ name;
29
+ markup;
30
+ style;
31
+ globalStyle;
32
+ uniClass;
33
+ constructor(name, struct) {
34
+ this.name = name;
35
+ if (struct.markup && struct.markupURL)
36
+ throw new Error(`[Implementation:${name}]: Both markup and markupURL provided.`);
37
+ this.markup = struct.markupURL ? Fetcher.fetchText(struct.markupURL) : Promise.resolve(struct.markup);
38
+ if (struct.css && struct.cssURL)
39
+ throw new Error(`[Implementation:${name}]: Both css and cssURL provided.`);
40
+ this.style = struct.cssURL ? Fetcher.fetchText(struct.cssURL) : Promise.resolve(struct.css);
41
+ if (struct.ltCss && struct.ltCssURL)
42
+ throw new Error(`[Implementation:${name}]: Both ltCss and ltCssURL provided.`);
43
+ this.globalStyle = struct.ltCssURL ? Fetcher.fetchText(struct.ltCssURL) : Promise.resolve(struct.ltCss);
44
+ this.uniClass = struct.class;
45
+ }
46
+ }
47
+ /**
48
+ * Placeholder — manages a named slot (tag or route) with swappable implementations.
49
+ *
50
+ * - `Placeholder.get(name)` — get or create a placeholder
51
+ * - `placeholder.addImplementation(impl)` — register an implementation
52
+ * - `Placeholder.switchTo(name, implName)` — globally switch + reload all instances
53
+ * - `Placeholder.switchInstance(instance, implName)` — switch one instance
54
+ */
55
+ export class Placeholder {
56
+ /** Все зарегистрированные placeholders по имени (tag / route). */
57
+ static _all = new Map();
58
+ name;
59
+ implementations = new Map();
60
+ activeImpl = new Observable(null);
61
+ /** Все живые экземпляры этого placeholder для reload при смене implementation. */
62
+ _instances = new Set();
63
+ constructor(name) {
64
+ this.name = name;
65
+ }
66
+ /** Get or create a placeholder by name. */
67
+ static get(name) {
68
+ let p = this._all.get(name);
69
+ if (!p) {
70
+ p = new Placeholder(name);
71
+ this._all.set(name, p);
72
+ }
73
+ return p;
74
+ }
75
+ /** Check if a placeholder exists. */
76
+ static has(name) {
77
+ return this._all.has(name);
78
+ }
79
+ /** Add an implementation. The first one added becomes active by default. */
80
+ addImplementation(impl) {
81
+ if (this.implementations.has(impl.name)) {
82
+ console.warn(`[Placeholder:${this.name}]: Implementation "${impl.name}" already registered, overwriting.`);
83
+ }
84
+ this.implementations.set(impl.name, impl);
85
+ if (!this.activeImpl.getObject()) {
86
+ this.activeImpl.setObject(impl);
87
+ console.info(`[Placeholder:${this.name}]: Default implementation set to "${impl.name}"`);
88
+ }
89
+ else {
90
+ console.info(`[Placeholder:${this.name}]: Implementation "${impl.name}" registered`);
91
+ }
92
+ }
93
+ /** Get the currently active implementation. */
94
+ getActive() {
95
+ return this.activeImpl.getObject();
96
+ }
97
+ /** Track a live instance for reload. */
98
+ trackInstance(instance) {
99
+ this._instances.add(instance);
100
+ }
101
+ /** Untrack a disposed instance. */
102
+ untrackInstance(instance) {
103
+ this._instances.delete(instance);
104
+ }
105
+ /** Get all tracked live instances. */
106
+ getInstances() {
107
+ return this._instances;
108
+ }
109
+ /**
110
+ * Switch the active implementation globally.
111
+ * All live instances of this placeholder will reload.
112
+ */
113
+ static async switchTo(placeholderName, implName) {
114
+ const p = this._all.get(placeholderName);
115
+ if (!p)
116
+ throw new Error(`[Placeholder]: "${placeholderName}" not found.`);
117
+ const impl = p.implementations.get(implName);
118
+ if (!impl)
119
+ throw new Error(`[Placeholder:${placeholderName}]: Implementation "${implName}" not found.`);
120
+ const prev = p.activeImpl.getObject();
121
+ if (prev === impl)
122
+ return;
123
+ p.activeImpl.setObject(impl);
124
+ console.info(`[Placeholder:${placeholderName}]: Switched to "${implName}"`);
125
+ // Reload all live instances
126
+ const reloads = [];
127
+ for (const instance of p._instances) {
128
+ reloads.push(instance.reload());
129
+ }
130
+ await Promise.all(reloads);
131
+ console.info(`[Placeholder:${placeholderName}]: Reloaded ${reloads.length} instance(s)`);
132
+ }
133
+ /**
134
+ * Switch a single instance to a different implementation and reload it.
135
+ * Does NOT change the global active implementation.
136
+ */
137
+ static async switchInstance(placeholderName, instance, implName) {
138
+ const p = this._all.get(placeholderName);
139
+ if (!p)
140
+ throw new Error(`[Placeholder]: "${placeholderName}" not found.`);
141
+ const impl = p.implementations.get(implName);
142
+ if (!impl)
143
+ throw new Error(`[Placeholder:${placeholderName}]: Implementation "${implName}" not found.`);
144
+ instance._activeImplementation = impl;
145
+ await instance.reload();
146
+ console.info(`[Placeholder:${placeholderName}]: Instance switched to "${implName}"`);
147
+ }
148
+ }
149
+ //# sourceMappingURL=Injection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Injection.js","sourceRoot":"","sources":["../../src/foundation/Injection.ts"],"names":[],"mappings":"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"}
@@ -1,37 +1,42 @@
1
- import UniHtml from "./component_api/UniHtml.js";
2
- import { AnyConstructor } from "./component_api/mixin/Proto.js";
1
+ import { ImplementationStruct } from "./Injection.js";
2
+ export declare const REGISTRY: (() => void)[];
3
3
  export declare enum AccessType {
4
4
  NONE = 0,
5
5
  OFFLINE = 1,
6
6
  ONLINE = 2,
7
7
  BOTH = 3
8
8
  }
9
- export type TripletStruct = {
10
- markupURL?: string;
11
- markup?: string;
12
- cssURL?: string;
13
- css?: string;
14
- ltCssURL?: string;
15
- ltCss?: string;
16
- jsURL?: string;
9
+ export type TripletStruct = ImplementationStruct & {
17
10
  access?: AccessType;
18
- class?: AnyConstructor<UniHtml>;
19
11
  };
12
+ /**
13
+ * Triplet — registers a placeholder with a default implementation.
14
+ *
15
+ * The placeholder is what gets registered in `customElements.define()` or `Router`.
16
+ * At runtime, the placeholder resolves the currently active {@link Implementation}
17
+ * and uses its markup, style, and class for the lifecycle.
18
+ *
19
+ * ```ts
20
+ * // Default implementation registered via @ReComponent
21
+ * @ReComponent({ markupURL: './Button.hmle', cssURL: './Button.css' }, "re-button")
22
+ * class ReButton extends Component { ... }
23
+ *
24
+ * // Alternative implementation registered via @ReImplementation
25
+ * @ReImplementation({ markupURL: './FancyButton.hmle', cssURL: './Fancy.css' }, "re-button")
26
+ * class FancyButton extends Component { ... }
27
+ *
28
+ * // Switch globally — all re-button instances reload
29
+ * Placeholder.switchTo("re-button", "FancyButton");
30
+ *
31
+ * // Switch one instance only
32
+ * Placeholder.switchInstance("re-button", myBtnInstance, "FancyButton");
33
+ * ```
34
+ */
20
35
  export default class Triplet {
21
- readonly markup?: Promise<string>;
22
- readonly css?: Promise<string>;
23
- readonly lightCss?: Promise<string>;
24
- readonly js?: Promise<string>;
25
- private readonly markupURL?;
26
- private readonly cssURL?;
27
- private readonly ltCssURL?;
28
- private readonly jsURL?;
29
36
  private readonly access;
30
- private uni?;
31
- constructor(struct: TripletStruct);
32
- init(): Promise<boolean>;
33
- cache(): Promise<void>;
34
- register(type: "router" | "markup", name: string): Promise<boolean>;
35
- private createInjectedClass;
37
+ private readonly placeholderName?;
38
+ private readonly implementation;
39
+ constructor(struct: TripletStruct, implName?: string);
40
+ register(type: "router" | "markup", name: string): Promise<void>;
36
41
  }
37
42
  //# sourceMappingURL=Triplet.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Triplet.d.ts","sourceRoot":"","sources":["../../src/foundation/Triplet.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,4BAA4B,CAAC;AAKjD,OAAO,EAAE,cAAc,EAAe,MAAM,gCAAgC,CAAC;AAK7E,oBAAY,UAAU;IAClB,IAAI,IAAI;IACR,OAAO,IAAS;IAChB,MAAM,IAAS;IACf,IAAI,IAAmB;CAC1B;AACD,MAAM,MAAM,aAAa,GAAG;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;CACnC,CAAA;AACD,MAAM,CAAC,OAAO,OAAO,OAAO;IACxB,SAAgB,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,SAAgB,GAAG,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,SAAgB,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,SAAgB,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAErC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAS;IAEhC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IAEpC,OAAO,CAAC,GAAG,CAAC,CAA0B;gBAEnB,MAAM,EAAE,aAAa;IA6B3B,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAcxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmDhF,OAAO,CAAC,mBAAmB;CAgC9B"}
1
+ {"version":3,"file":"Triplet.d.ts","sourceRoot":"","sources":["../../src/foundation/Triplet.ts"],"names":[],"mappings":"AAQA,OAAO,EAAkB,oBAAoB,EAAe,MAAM,gBAAgB,CAAC;AAEnF,eAAO,MAAM,QAAQ,EAAE,CAAC,MAAM,IAAI,CAAC,EAAO,CAAC;AAE3C,oBAAY,UAAU;IAClB,IAAI,IAAI;IACR,OAAO,IAAS;IAChB,MAAM,IAAS;IACf,IAAI,IAAmB;CAC1B;AAED,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG;IAC/C,MAAM,CAAC,EAAE,UAAU,CAAC;CACvB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,OAAO,OAAO,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;gBAE7B,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,MAAM;IAO9C,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4FhF"}
@@ -1,10 +1,10 @@
1
- import Fetcher from "./Fetcher.js";
2
1
  import { Router } from "./worker/Router.js";
3
- import ServiceWorker from "./worker/ServiceWorker.js";
4
2
  import Page from "./component_api/Page.js";
5
3
  import Component from "./component_api/Component.js";
6
4
  import TemplateEngine from "./engine/TemplateEngine.js";
7
5
  import Scope from "./engine/Scope.js";
6
+ import { Implementation, Placeholder } from "./Injection.js";
7
+ export const REGISTRY = [];
8
8
  export var AccessType;
9
9
  (function (AccessType) {
10
10
  AccessType[AccessType["NONE"] = 0] = "NONE";
@@ -12,131 +12,112 @@ export var AccessType;
12
12
  AccessType[AccessType["ONLINE"] = 2] = "ONLINE";
13
13
  AccessType[AccessType["BOTH"] = 3] = "BOTH";
14
14
  })(AccessType || (AccessType = {}));
15
+ /**
16
+ * Triplet — registers a placeholder with a default implementation.
17
+ *
18
+ * The placeholder is what gets registered in `customElements.define()` or `Router`.
19
+ * At runtime, the placeholder resolves the currently active {@link Implementation}
20
+ * and uses its markup, style, and class for the lifecycle.
21
+ *
22
+ * ```ts
23
+ * // Default implementation registered via @ReComponent
24
+ * @ReComponent({ markupURL: './Button.hmle', cssURL: './Button.css' }, "re-button")
25
+ * class ReButton extends Component { ... }
26
+ *
27
+ * // Alternative implementation registered via @ReImplementation
28
+ * @ReImplementation({ markupURL: './FancyButton.hmle', cssURL: './Fancy.css' }, "re-button")
29
+ * class FancyButton extends Component { ... }
30
+ *
31
+ * // Switch globally — all re-button instances reload
32
+ * Placeholder.switchTo("re-button", "FancyButton");
33
+ *
34
+ * // Switch one instance only
35
+ * Placeholder.switchInstance("re-button", myBtnInstance, "FancyButton");
36
+ * ```
37
+ */
15
38
  export default class Triplet {
16
- markup;
17
- css;
18
- lightCss;
19
- js;
20
- markupURL;
21
- cssURL;
22
- ltCssURL;
23
- jsURL;
24
39
  access;
25
- uni;
26
- constructor(struct) {
27
- this.markupURL = struct.markupURL;
28
- this.cssURL = struct.cssURL;
29
- this.ltCssURL = struct.ltCssURL;
30
- this.jsURL = struct.jsURL;
31
- let markup = Promise.resolve(struct.markup);
32
- if (struct.markupURL)
33
- markup = Fetcher.fetchText(struct.markupURL);
34
- let css = Promise.resolve(struct.css);
35
- if (struct.cssURL)
36
- css = Fetcher.fetchText(struct.cssURL);
37
- let ltCss = Promise.resolve(struct.ltCss);
38
- if (struct.ltCssURL)
39
- ltCss = Fetcher.fetchText(struct.ltCssURL);
40
- /*let js = Promise.resolve(undefined);
41
- if (struct.jsURL)
42
- js = Fetcher.fetchText(struct.jsURL);*/
43
- this.markup = markup;
44
- this.css = css;
45
- this.lightCss = ltCss;
46
- //this.js = js;
40
+ placeholderName;
41
+ implementation;
42
+ constructor(struct, implName) {
47
43
  this.access = struct.access ?? AccessType.BOTH;
48
- this.uni = struct.class;
49
- }
50
- async init() {
51
- const isOnline = await ServiceWorker.isOnline();
52
- if (this.access === AccessType.NONE)
53
- return false;
54
- if (this.access === AccessType.BOTH) {
55
- await this.cache();
56
- return true;
57
- }
58
- ;
59
- if (this.access === AccessType.OFFLINE && isOnline)
60
- return false;
61
- if (this.access === AccessType.ONLINE && !isOnline)
62
- return false;
63
- return true;
64
- }
65
- async cache() {
66
- //
44
+ const name = implName ?? struct.class?.name ?? "default";
45
+ this.implementation = new Implementation(name, struct);
67
46
  }
68
47
  async register(type, name) {
69
- if (!this.uni) {
70
- switch (type) {
71
- case "router":
72
- this.uni = Page;
73
- break;
74
- case "markup":
75
- this.uni = Component;
76
- break;
77
- }
48
+ const placeholder = Placeholder.get(name);
49
+ placeholder.addImplementation(this.implementation);
50
+ // If the placeholder already has a registered element/route, skip re-registration
51
+ if (placeholder.implementations.size > 1) {
52
+ console.info(`[Triplet]: Implementation "${this.implementation.name}" added to existing placeholder "${name}"`);
53
+ return;
78
54
  }
79
- if (this.lightCss) {
80
- var style = await new CSSStyleSheet().replace(await this.lightCss);
81
- document.adoptedStyleSheets = [
82
- ...document.adoptedStyleSheets,
83
- style
84
- ];
85
- }
86
- let ori = this.createInjectedClass(this.uni, type);
55
+ // First implementation — register the placeholder shell
87
56
  if (type === "router") {
88
- const routePath = this.markupURL ?? "";
89
- var reg = Router.registerRoute(routePath, name, (search) => {
90
- const paramNames = (() => {
91
- const ctor = this.uni.prototype.constructor;
92
- const fnStr = ctor.toString();
93
- const argsMatch = fnStr.match(/constructor\s*\(([^)]*)\)/);
94
- if (!argsMatch)
95
- return [];
96
- return argsMatch[1].split(',').map(s => s.trim()).filter(Boolean);
97
- })();
98
- const args = paramNames.map(name => {
99
- return search?.get(name);
57
+ REGISTRY.push(() => {
58
+ const routePath = name;
59
+ Router.registerRoute("", routePath, (search) => {
60
+ const impl = placeholder.getActive();
61
+ const cls = impl.uniClass ?? Page;
62
+ const paramNames = (() => {
63
+ const ctor = cls.prototype.constructor;
64
+ const fnStr = ctor.toString();
65
+ const argsMatch = fnStr.match(/constructor\s*\(([^)]*)\)/);
66
+ if (!argsMatch)
67
+ return [];
68
+ return argsMatch[1].split(',').map(s => s.trim()).filter(Boolean);
69
+ })();
70
+ const args = paramNames.map(n => search?.get(n));
71
+ const instance = new cls(...args);
72
+ // Attach placeholder context to instance for _init resolution
73
+ instance._placeholderName = name;
74
+ instance._activeImplementation = impl;
75
+ placeholder.trackInstance(instance);
76
+ return instance;
100
77
  });
101
- return new ori(...args);
78
+ console.info(`[Triplet]: Router route "${name}" registered as placeholder`);
102
79
  });
103
- console.info(`[Triplet]` + `: Router route '${name}' registered for path '${routePath}' by class ${ori}.`);
104
- return reg.then(() => true).catch(() => false);
105
80
  }
106
81
  else if (type === "markup") {
107
- if (customElements.get(name))
108
- throw new Error(`Custom element '${name}' is already defined.`);
109
- customElements.define(name, ori.prototype.constructor);
110
- console.info(`[Triplet]: Custom element '${name}' defined.`);
111
- return Promise.resolve(true);
82
+ REGISTRY.push(() => {
83
+ if (customElements.get(name))
84
+ throw new Error(`Custom element '${name}' is already defined.`);
85
+ const cls = this.implementation.uniClass ?? Component;
86
+ const placeholderRef = placeholder;
87
+ const placeholderName = name;
88
+ // Create the placeholder class that delegates to the active implementation
89
+ let proto = cls.prototype;
90
+ proto._init = async function () {
91
+ // Resolve which implementation to use (per-instance override or global)
92
+ const impl = this._activeImplementation
93
+ ?? placeholderRef.getActive();
94
+ if (!impl)
95
+ throw new Error(`[Placeholder:${placeholderName}]: No active implementation.`);
96
+ // Store for reload
97
+ this._placeholderName = placeholderName;
98
+ if (!this._activeImplementation)
99
+ this._activeImplementation = impl;
100
+ placeholderRef.trackInstance(this);
101
+ // Load markup
102
+ const markupText = await impl.markup;
103
+ const holder = TemplateEngine.createHolder(markupText, Scope.from(this));
104
+ // Apply scoped CSS
105
+ const dmc = this.shadowRoot ?? document;
106
+ const cssText = await impl.style;
107
+ if (cssText) {
108
+ dmc.adoptedStyleSheets.push(await new CSSStyleSheet().replace(cssText));
109
+ }
110
+ // Apply global CSS
111
+ const globalCss = await impl.globalStyle;
112
+ if (globalCss) {
113
+ document.adoptedStyleSheets.push(await new CSSStyleSheet().replace(globalCss));
114
+ }
115
+ return holder;
116
+ };
117
+ customElements.define(name, cls.prototype.constructor);
118
+ console.info(`[Triplet]: Custom element "${name}" registered as placeholder`);
119
+ });
112
120
  }
113
- return Promise.resolve(false);
114
- }
115
- createInjectedClass(c, type) {
116
- let that = this;
117
- let ori = class extends c {
118
- constructor(...args) {
119
- super(...args);
120
- }
121
- };
122
- let proto = ori.prototype;
123
- const parser = new TemplateEngine();
124
- proto._init = async function () {
125
- const markupText = await that.markup;
126
- return TemplateEngine.createHolder(markupText, Scope.from(this));
127
- };
128
- proto._postInit = async function (preHtml) {
129
- const dmc = this.shadowRoot ?? document;
130
- const css = await that.css;
131
- var style = await new CSSStyleSheet().replace(css);
132
- dmc.adoptedStyleSheets = [
133
- ...dmc.adoptedStyleSheets,
134
- style
135
- ];
136
- //parser.hydrate(preHtml, this);
137
- return preHtml;
138
- };
139
- return ori;
140
121
  }
141
122
  }
142
123
  //# sourceMappingURL=Triplet.js.map