@reidelsaltres/pureper 0.2.28 → 0.2.29
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.
- package/out/foundation/Module.d.ts +48 -0
- package/out/foundation/Module.d.ts.map +1 -0
- package/out/foundation/Module.js +141 -0
- package/out/foundation/Module.js.map +1 -0
- package/out/index.d.ts +1 -0
- package/out/index.d.ts.map +1 -1
- package/out/index.js +1 -0
- package/out/index.js.map +1 -1
- package/package.json +1 -1
- package/src/foundation/Module.ts +163 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import Observable from "./api/Observer.js";
|
|
2
|
+
export type ModuleStruct = {
|
|
3
|
+
name: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
icon?: string;
|
|
6
|
+
core?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export default class Module {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly description?: string;
|
|
11
|
+
readonly icon?: string;
|
|
12
|
+
readonly core: boolean;
|
|
13
|
+
readonly enabled: Observable<boolean>;
|
|
14
|
+
private _registrations;
|
|
15
|
+
constructor(struct: ModuleStruct);
|
|
16
|
+
addRegistration(fn: () => Promise<void>): void;
|
|
17
|
+
getRegistrations(): ReadonlyArray<() => Promise<void>>;
|
|
18
|
+
/**
|
|
19
|
+
* Takes current entries from the global REGISTRY, moves them into this
|
|
20
|
+
* module's internal list, and removes them from REGISTRY.
|
|
21
|
+
*
|
|
22
|
+
* Call this in consumer code AFTER importing the module's components so
|
|
23
|
+
* that all their REGISTRY entries have been pushed.
|
|
24
|
+
*/
|
|
25
|
+
captureRegistrations(registry: (() => Promise<void>)[]): void;
|
|
26
|
+
enable(): void;
|
|
27
|
+
disable(): void;
|
|
28
|
+
isActive(): boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare class ModuleManager {
|
|
31
|
+
private static _modules;
|
|
32
|
+
private static readonly STORAGE_KEY;
|
|
33
|
+
static register(struct: ModuleStruct): Module;
|
|
34
|
+
static get(name: string): Module | undefined;
|
|
35
|
+
static getAll(): Module[];
|
|
36
|
+
static isActive(name: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Initializes all modules:
|
|
39
|
+
* 1. Restores saved enabled/disabled preferences
|
|
40
|
+
* 2. Runs registrations from all enabled modules
|
|
41
|
+
* 3. Runs any remaining global REGISTRY entries (backward compat)
|
|
42
|
+
* 4. Returns all promises
|
|
43
|
+
*/
|
|
44
|
+
static initialize(): Promise<void>[];
|
|
45
|
+
static persistState(): void;
|
|
46
|
+
static restoreState(): void;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=Module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Module.d.ts","sourceRoot":"","sources":["../../src/foundation/Module.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAG3C,MAAM,MAAM,YAAY,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,MAAM;IACvB,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrC,SAAgB,IAAI,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAgB,IAAI,EAAE,OAAO,CAAC;IAC9B,SAAgB,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAE7C,OAAO,CAAC,cAAc,CAA+B;gBAElC,MAAM,EAAE,YAAY;IAQhC,eAAe,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAI9C,gBAAgB,IAAI,aAAa,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAI7D;;;;;;OAMG;IACI,oBAAoB,CAAC,QAAQ,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,IAAI;IAM7D,MAAM,IAAI,IAAI;IAMd,OAAO,IAAI,IAAI;IASf,QAAQ,IAAI,OAAO;CAG7B;AAED,qBAAa,aAAa;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IACzD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAEvD,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM;IAU7C,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI5C,MAAM,CAAC,MAAM,IAAI,MAAM,EAAE;IAIzB,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAKtC;;;;;;OAMG;IACH,MAAM,CAAC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;IA4BpC,MAAM,CAAC,YAAY,IAAI,IAAI;IAe3B,MAAM,CAAC,YAAY,IAAI,IAAI;CAiB9B"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import Observable from "./api/Observer.js";
|
|
2
|
+
import { REGISTRY } from "./Triplet.js";
|
|
3
|
+
export default class Module {
|
|
4
|
+
name;
|
|
5
|
+
description;
|
|
6
|
+
icon;
|
|
7
|
+
core;
|
|
8
|
+
enabled;
|
|
9
|
+
_registrations = [];
|
|
10
|
+
constructor(struct) {
|
|
11
|
+
this.name = struct.name;
|
|
12
|
+
this.description = struct.description;
|
|
13
|
+
this.icon = struct.icon;
|
|
14
|
+
this.core = struct.core ?? false;
|
|
15
|
+
this.enabled = new Observable(this.core ? true : true);
|
|
16
|
+
}
|
|
17
|
+
addRegistration(fn) {
|
|
18
|
+
this._registrations.push(fn);
|
|
19
|
+
}
|
|
20
|
+
getRegistrations() {
|
|
21
|
+
return this._registrations;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Takes current entries from the global REGISTRY, moves them into this
|
|
25
|
+
* module's internal list, and removes them from REGISTRY.
|
|
26
|
+
*
|
|
27
|
+
* Call this in consumer code AFTER importing the module's components so
|
|
28
|
+
* that all their REGISTRY entries have been pushed.
|
|
29
|
+
*/
|
|
30
|
+
captureRegistrations(registry) {
|
|
31
|
+
const captured = registry.splice(0, registry.length);
|
|
32
|
+
this._registrations.push(...captured);
|
|
33
|
+
console.log(`[Module]: "${this.name}" captured ${captured.length} registration(s)`);
|
|
34
|
+
}
|
|
35
|
+
enable() {
|
|
36
|
+
if (this.enabled.getObject() === true)
|
|
37
|
+
return;
|
|
38
|
+
this.enabled.setObject(true);
|
|
39
|
+
console.log(`[Module]: "${this.name}" enabled`);
|
|
40
|
+
}
|
|
41
|
+
disable() {
|
|
42
|
+
if (this.core) {
|
|
43
|
+
throw new Error(`[Module]: Cannot disable core module "${this.name}"`);
|
|
44
|
+
}
|
|
45
|
+
if (this.enabled.getObject() === false)
|
|
46
|
+
return;
|
|
47
|
+
this.enabled.setObject(false);
|
|
48
|
+
console.log(`[Module]: "${this.name}" disabled`);
|
|
49
|
+
}
|
|
50
|
+
isActive() {
|
|
51
|
+
return this.enabled.getObject() === true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export class ModuleManager {
|
|
55
|
+
static _modules = new Map();
|
|
56
|
+
static STORAGE_KEY = "purper:modules";
|
|
57
|
+
static register(struct) {
|
|
58
|
+
if (this._modules.has(struct.name)) {
|
|
59
|
+
throw new Error(`[Module]: Module "${struct.name}" is already registered`);
|
|
60
|
+
}
|
|
61
|
+
const mod = new Module(struct);
|
|
62
|
+
this._modules.set(struct.name, mod);
|
|
63
|
+
console.log(`[Module]: Registered module "${struct.name}"`);
|
|
64
|
+
return mod;
|
|
65
|
+
}
|
|
66
|
+
static get(name) {
|
|
67
|
+
return this._modules.get(name);
|
|
68
|
+
}
|
|
69
|
+
static getAll() {
|
|
70
|
+
return Array.from(this._modules.values());
|
|
71
|
+
}
|
|
72
|
+
static isActive(name) {
|
|
73
|
+
const mod = this._modules.get(name);
|
|
74
|
+
return mod ? mod.isActive() : false;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Initializes all modules:
|
|
78
|
+
* 1. Restores saved enabled/disabled preferences
|
|
79
|
+
* 2. Runs registrations from all enabled modules
|
|
80
|
+
* 3. Runs any remaining global REGISTRY entries (backward compat)
|
|
81
|
+
* 4. Returns all promises
|
|
82
|
+
*/
|
|
83
|
+
static initialize() {
|
|
84
|
+
this.restoreState();
|
|
85
|
+
const promises = [];
|
|
86
|
+
for (const mod of this._modules.values()) {
|
|
87
|
+
if (mod.isActive()) {
|
|
88
|
+
console.log(`[Module]: Initializing module "${mod.name}" (${mod.getRegistrations().length} registration(s))`);
|
|
89
|
+
for (const reg of mod.getRegistrations()) {
|
|
90
|
+
promises.push(reg());
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.log(`[Module]: Skipping disabled module "${mod.name}"`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Backward compat: run any remaining global REGISTRY entries
|
|
98
|
+
// that were not captured by any module
|
|
99
|
+
if (REGISTRY.length > 0) {
|
|
100
|
+
console.log(`[Module]: Running ${REGISTRY.length} uncaptured global registration(s)`);
|
|
101
|
+
for (const reg of REGISTRY) {
|
|
102
|
+
promises.push(reg());
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return promises;
|
|
106
|
+
}
|
|
107
|
+
static persistState() {
|
|
108
|
+
const state = {};
|
|
109
|
+
for (const mod of this._modules.values()) {
|
|
110
|
+
if (!mod.core) {
|
|
111
|
+
state[mod.name] = mod.isActive();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(state));
|
|
116
|
+
console.log(`[Module]: Persisted module state`);
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
console.warn(`[Module]: Failed to persist module state`, e);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
static restoreState() {
|
|
123
|
+
try {
|
|
124
|
+
const raw = localStorage.getItem(this.STORAGE_KEY);
|
|
125
|
+
if (!raw)
|
|
126
|
+
return;
|
|
127
|
+
const state = JSON.parse(raw);
|
|
128
|
+
for (const [name, enabled] of Object.entries(state)) {
|
|
129
|
+
const mod = this._modules.get(name);
|
|
130
|
+
if (mod && !mod.core) {
|
|
131
|
+
mod.enabled.setObject(enabled);
|
|
132
|
+
console.log(`[Module]: Restored "${name}" → ${enabled ? "enabled" : "disabled"}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch (e) {
|
|
137
|
+
console.warn(`[Module]: Failed to restore module state`, e);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=Module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Module.js","sourceRoot":"","sources":["../../src/foundation/Module.ts"],"names":[],"mappings":"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"}
|
package/out/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export { default as Attribute } from './foundation/component_api/Attribute.js';
|
|
|
10
10
|
export { default as Triplet, TripletStruct, AccessType, REGISTRY } from './foundation/Triplet.js';
|
|
11
11
|
export { ReComponent, RePage, ReImplementation } from './foundation/TripletDecorator.js';
|
|
12
12
|
export { Implementation, ImplementationStruct, Placeholder } from './foundation/Injection.js';
|
|
13
|
+
export { default as Module, ModuleStruct, ModuleManager } from './foundation/Module.js';
|
|
13
14
|
export { default as Fetcher } from './foundation/Fetcher.js';
|
|
14
15
|
export * from './foundation/engine/TemplateEngine.js';
|
|
15
16
|
export { Router } from './foundation/worker/Router.js';
|
package/out/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE3D,cAAc,2CAA2C,CAAC;AAC1D,OAAO,EACN,OAAO,IAAI,UAAU,EACrB,SAAS,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAC3F,YAAY,EACZ,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAE7D,cAAc,uCAAuC,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAErK,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE3D,cAAc,2CAA2C,CAAC;AAC1D,OAAO,EACN,OAAO,IAAI,UAAU,EACrB,SAAS,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAC3F,YAAY,EACZ,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAE7D,cAAc,uCAAuC,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAErK,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC"}
|
package/out/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { default as Attribute } from './foundation/component_api/Attribute.js';
|
|
|
8
8
|
export { default as Triplet, AccessType, REGISTRY } from './foundation/Triplet.js';
|
|
9
9
|
export { ReComponent, RePage, ReImplementation } from './foundation/TripletDecorator.js';
|
|
10
10
|
export { Implementation, Placeholder } from './foundation/Injection.js';
|
|
11
|
+
export { default as Module, ModuleManager } from './foundation/Module.js';
|
|
11
12
|
export { default as Fetcher } from './foundation/Fetcher.js';
|
|
12
13
|
export * from './foundation/engine/TemplateEngine.js';
|
|
13
14
|
export { Router } from './foundation/worker/Router.js';
|
package/out/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE3D,cAAc,2CAA2C,CAAC;AAC1D,OAAO,EACN,OAAO,IAAI,UAAU,EAC+B,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAC3F,YAAY,EACZ,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAiB,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzF,OAAO,EAAE,cAAc,EAAwB,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAE7D,cAAc,uCAAuC,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAuF,MAAM,sCAAsC,CAAC;AAErK,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AAGtC,qEAAqE;AACrE;;WAEQ;AAER,yEAAyE"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE3D,cAAc,2CAA2C,CAAC;AAC1D,OAAO,EACN,OAAO,IAAI,UAAU,EAC+B,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAC3F,YAAY,EACZ,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAiB,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzF,OAAO,EAAE,cAAc,EAAwB,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,MAAM,EAAgB,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAE7D,cAAc,uCAAuC,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAuF,MAAM,sCAAsC,CAAC;AAErK,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AAGtC,qEAAqE;AACrE;;WAEQ;AAER,yEAAyE"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import Observable from "./api/Observer.js";
|
|
2
|
+
import { REGISTRY } from "./Triplet.js";
|
|
3
|
+
|
|
4
|
+
export type ModuleStruct = {
|
|
5
|
+
name: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
icon?: string;
|
|
8
|
+
core?: boolean;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default class Module {
|
|
12
|
+
public readonly name: string;
|
|
13
|
+
public readonly description?: string;
|
|
14
|
+
public readonly icon?: string;
|
|
15
|
+
public readonly core: boolean;
|
|
16
|
+
public readonly enabled: Observable<boolean>;
|
|
17
|
+
|
|
18
|
+
private _registrations: (() => Promise<void>)[] = [];
|
|
19
|
+
|
|
20
|
+
public constructor(struct: ModuleStruct) {
|
|
21
|
+
this.name = struct.name;
|
|
22
|
+
this.description = struct.description;
|
|
23
|
+
this.icon = struct.icon;
|
|
24
|
+
this.core = struct.core ?? false;
|
|
25
|
+
this.enabled = new Observable<boolean>(this.core ? true : true);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public addRegistration(fn: () => Promise<void>): void {
|
|
29
|
+
this._registrations.push(fn);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public getRegistrations(): ReadonlyArray<() => Promise<void>> {
|
|
33
|
+
return this._registrations;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Takes current entries from the global REGISTRY, moves them into this
|
|
38
|
+
* module's internal list, and removes them from REGISTRY.
|
|
39
|
+
*
|
|
40
|
+
* Call this in consumer code AFTER importing the module's components so
|
|
41
|
+
* that all their REGISTRY entries have been pushed.
|
|
42
|
+
*/
|
|
43
|
+
public captureRegistrations(registry: (() => Promise<void>)[]): void {
|
|
44
|
+
const captured = registry.splice(0, registry.length);
|
|
45
|
+
this._registrations.push(...captured);
|
|
46
|
+
console.log(`[Module]: "${this.name}" captured ${captured.length} registration(s)`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public enable(): void {
|
|
50
|
+
if (this.enabled.getObject() === true) return;
|
|
51
|
+
this.enabled.setObject(true);
|
|
52
|
+
console.log(`[Module]: "${this.name}" enabled`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public disable(): void {
|
|
56
|
+
if (this.core) {
|
|
57
|
+
throw new Error(`[Module]: Cannot disable core module "${this.name}"`);
|
|
58
|
+
}
|
|
59
|
+
if (this.enabled.getObject() === false) return;
|
|
60
|
+
this.enabled.setObject(false);
|
|
61
|
+
console.log(`[Module]: "${this.name}" disabled`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public isActive(): boolean {
|
|
65
|
+
return this.enabled.getObject() === true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export class ModuleManager {
|
|
70
|
+
private static _modules: Map<string, Module> = new Map();
|
|
71
|
+
private static readonly STORAGE_KEY = "purper:modules";
|
|
72
|
+
|
|
73
|
+
static register(struct: ModuleStruct): Module {
|
|
74
|
+
if (this._modules.has(struct.name)) {
|
|
75
|
+
throw new Error(`[Module]: Module "${struct.name}" is already registered`);
|
|
76
|
+
}
|
|
77
|
+
const mod = new Module(struct);
|
|
78
|
+
this._modules.set(struct.name, mod);
|
|
79
|
+
console.log(`[Module]: Registered module "${struct.name}"`);
|
|
80
|
+
return mod;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static get(name: string): Module | undefined {
|
|
84
|
+
return this._modules.get(name);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static getAll(): Module[] {
|
|
88
|
+
return Array.from(this._modules.values());
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static isActive(name: string): boolean {
|
|
92
|
+
const mod = this._modules.get(name);
|
|
93
|
+
return mod ? mod.isActive() : false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Initializes all modules:
|
|
98
|
+
* 1. Restores saved enabled/disabled preferences
|
|
99
|
+
* 2. Runs registrations from all enabled modules
|
|
100
|
+
* 3. Runs any remaining global REGISTRY entries (backward compat)
|
|
101
|
+
* 4. Returns all promises
|
|
102
|
+
*/
|
|
103
|
+
static initialize(): Promise<void>[] {
|
|
104
|
+
this.restoreState();
|
|
105
|
+
|
|
106
|
+
const promises: Promise<void>[] = [];
|
|
107
|
+
|
|
108
|
+
for (const mod of this._modules.values()) {
|
|
109
|
+
if (mod.isActive()) {
|
|
110
|
+
console.log(`[Module]: Initializing module "${mod.name}" (${mod.getRegistrations().length} registration(s))`);
|
|
111
|
+
for (const reg of mod.getRegistrations()) {
|
|
112
|
+
promises.push(reg());
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
console.log(`[Module]: Skipping disabled module "${mod.name}"`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Backward compat: run any remaining global REGISTRY entries
|
|
120
|
+
// that were not captured by any module
|
|
121
|
+
if (REGISTRY.length > 0) {
|
|
122
|
+
console.log(`[Module]: Running ${REGISTRY.length} uncaptured global registration(s)`);
|
|
123
|
+
for (const reg of REGISTRY) {
|
|
124
|
+
promises.push(reg());
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return promises;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
static persistState(): void {
|
|
132
|
+
const state: Record<string, boolean> = {};
|
|
133
|
+
for (const mod of this._modules.values()) {
|
|
134
|
+
if (!mod.core) {
|
|
135
|
+
state[mod.name] = mod.isActive();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(state));
|
|
140
|
+
console.log(`[Module]: Persisted module state`);
|
|
141
|
+
} catch (e) {
|
|
142
|
+
console.warn(`[Module]: Failed to persist module state`, e);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
static restoreState(): void {
|
|
147
|
+
try {
|
|
148
|
+
const raw = localStorage.getItem(this.STORAGE_KEY);
|
|
149
|
+
if (!raw) return;
|
|
150
|
+
|
|
151
|
+
const state: Record<string, boolean> = JSON.parse(raw);
|
|
152
|
+
for (const [name, enabled] of Object.entries(state)) {
|
|
153
|
+
const mod = this._modules.get(name);
|
|
154
|
+
if (mod && !mod.core) {
|
|
155
|
+
mod.enabled.setObject(enabled);
|
|
156
|
+
console.log(`[Module]: Restored "${name}" → ${enabled ? "enabled" : "disabled"}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
} catch (e) {
|
|
160
|
+
console.warn(`[Module]: Failed to restore module state`, e);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -19,6 +19,7 @@ export { default as Triplet, TripletStruct, AccessType, REGISTRY } from './found
|
|
|
19
19
|
export { ReComponent, RePage, ReImplementation } from './foundation/TripletDecorator.js';
|
|
20
20
|
|
|
21
21
|
export { Implementation, ImplementationStruct, Placeholder } from './foundation/Injection.js';
|
|
22
|
+
export { default as Module, ModuleStruct, ModuleManager } from './foundation/Module.js';
|
|
22
23
|
export { default as Fetcher } from './foundation/Fetcher.js';
|
|
23
24
|
|
|
24
25
|
export * from './foundation/engine/TemplateEngine.js';
|