composed-di 0.0.3 → 0.0.4-alpha
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/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +12 -281
- package/dist/main.js.map +1 -0
- package/dist/serviceFactory.d.ts +7 -7
- package/dist/serviceFactory.d.ts.map +1 -1
- package/dist/serviceFactory.js.map +1 -1
- package/dist/serviceModule.d.ts +2 -2
- package/dist/serviceModule.d.ts.map +1 -1
- package/dist/serviceModule.js.map +1 -1
- package/package.json +1 -1
- package/src/main.ts +19 -0
- package/src/serviceFactory.ts +78 -69
- package/src/serviceModule.ts +7 -5
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}
|
package/dist/main.js
CHANGED
|
@@ -1,284 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
return to;
|
|
15
|
-
};
|
|
16
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
-
mod
|
|
23
|
-
));
|
|
24
|
-
|
|
25
|
-
// src/lib/serviceModule.ts
|
|
26
|
-
var ServiceModule = class _ServiceModule {
|
|
27
|
-
constructor(factories) {
|
|
28
|
-
this.factories = [];
|
|
29
|
-
this.factories = Array.from(factories);
|
|
30
|
-
this.factories.forEach((factory) => {
|
|
31
|
-
checkRecursiveDependencies(factory);
|
|
32
|
-
checkMissingDependencies(factory, this.factories);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
async inject(key) {
|
|
36
|
-
const factory = this.factories.find((factory2) => {
|
|
37
|
-
return isSuitable(key, factory2);
|
|
38
|
-
});
|
|
39
|
-
if (!factory) {
|
|
40
|
-
throw new Error(`Could not find a suitable factory for ${key.name}`);
|
|
41
|
-
}
|
|
42
|
-
const dependencies = await Promise.all(
|
|
43
|
-
factory.dependsOn.map((dependencyKey) => {
|
|
44
|
-
return this.inject(dependencyKey);
|
|
45
|
-
})
|
|
46
|
-
);
|
|
47
|
-
return factory.initialize(...dependencies);
|
|
48
|
-
}
|
|
49
|
-
static from(factories) {
|
|
50
|
-
return new _ServiceModule(new Set(factories));
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
function checkRecursiveDependencies(factory) {
|
|
54
|
-
const recursive = factory.dependsOn.some((dependencyKey) => {
|
|
55
|
-
return dependencyKey === factory.provides;
|
|
56
|
-
});
|
|
57
|
-
if (recursive) {
|
|
58
|
-
throw new Error(
|
|
59
|
-
"Recursive dependency detected on: " + factory.provides.name
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
function checkMissingDependencies(factory, factories) {
|
|
64
|
-
const missingDependencies = factory.dependsOn.filter(
|
|
65
|
-
(dependencyKey) => {
|
|
66
|
-
return !isRegistered(dependencyKey, factories);
|
|
67
|
-
}
|
|
68
|
-
);
|
|
69
|
-
if (missingDependencies.length === 0) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
const dependencyList = missingDependencies.map((dependencyKey) => ` -> ${dependencyKey.name}`).join("\n");
|
|
73
|
-
throw new Error(
|
|
74
|
-
`${factory.provides.name} will fail because it depends on:
|
|
75
|
-
${dependencyList}`
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
function isRegistered(key, factories) {
|
|
79
|
-
return factories.some((factory) => factory.provides === key);
|
|
80
|
-
}
|
|
81
|
-
function isSuitable(key, factory) {
|
|
82
|
-
return factory?.provides === key;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// src/lib/serviceKey.ts
|
|
86
|
-
var ServiceKey = class {
|
|
87
|
-
constructor(name) {
|
|
88
|
-
this.name = name;
|
|
89
|
-
this.symbol = Symbol(name);
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
// src/lib/serviceFactory.ts
|
|
94
|
-
function singletonFactory({
|
|
95
|
-
provides,
|
|
96
|
-
dependsOn = [],
|
|
97
|
-
initialize,
|
|
98
|
-
dispose = () => {
|
|
99
|
-
}
|
|
100
|
-
}) {
|
|
101
|
-
let instance;
|
|
102
|
-
return {
|
|
103
|
-
provides,
|
|
104
|
-
dependsOn,
|
|
105
|
-
async initialize(...dependencies) {
|
|
106
|
-
if (instance) {
|
|
107
|
-
return instance;
|
|
108
|
-
}
|
|
109
|
-
instance = await initialize(...dependencies);
|
|
110
|
-
return instance;
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const serviceKey_1 = require("./serviceKey");
|
|
4
|
+
const serviceFactory_1 = require("./serviceFactory");
|
|
5
|
+
const TEST_SERVICE_KEY = new serviceKey_1.ServiceKey('testService');
|
|
6
|
+
const FOO_KEY = new serviceKey_1.ServiceKey('foo');
|
|
7
|
+
const BAR_KEY = new serviceKey_1.ServiceKey('bar');
|
|
8
|
+
const TestServiceFactory = (0, serviceFactory_1.singletonFactory)({
|
|
9
|
+
provides: TEST_SERVICE_KEY,
|
|
10
|
+
dependsOn: [FOO_KEY, BAR_KEY],
|
|
11
|
+
initialize: (foo, bar) => {
|
|
12
|
+
return { foo, bar };
|
|
111
13
|
},
|
|
112
|
-
dispose(serviceInstance) {
|
|
113
|
-
if (instance === serviceInstance) {
|
|
114
|
-
dispose(serviceInstance);
|
|
115
|
-
instance = void 0;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// src/core/sms/di/smsModule.ts
|
|
122
|
-
var import_node_process = __toESM(require("node:process"));
|
|
123
|
-
|
|
124
|
-
// src/core/sms/noOpSmsService.ts
|
|
125
|
-
var NoOpSmsService = class {
|
|
126
|
-
send(recipient, text) {
|
|
127
|
-
console.warn(`NoOpSmsService: Sending sms to ${recipient}: ${text}`);
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
// src/core/sms/tigoSmsService.ts
|
|
132
|
-
var TigoSmsService = class {
|
|
133
|
-
send(_recipient, _text) {
|
|
134
|
-
throw new Error("Not yet implemented");
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
// src/core/logger/emailAlertLogger.ts
|
|
139
|
-
var EmailAlertLogger = class {
|
|
140
|
-
constructor(bufferSize = 50, recipients = []) {
|
|
141
|
-
this.buffer = [];
|
|
142
|
-
this.emailQueue = [];
|
|
143
|
-
this.bufferSize = bufferSize;
|
|
144
|
-
this.recipients = recipients;
|
|
145
|
-
}
|
|
146
|
-
addToBuffer(event) {
|
|
147
|
-
if (this.buffer.length >= this.bufferSize) {
|
|
148
|
-
this.buffer.shift();
|
|
149
|
-
}
|
|
150
|
-
this.buffer.push({ ...event, date: /* @__PURE__ */ new Date() });
|
|
151
|
-
}
|
|
152
|
-
info(message, payload) {
|
|
153
|
-
this.addToBuffer({ level: "INFO", message, payload });
|
|
154
|
-
}
|
|
155
|
-
error(message, error, payload) {
|
|
156
|
-
this.addToBuffer({ level: "ERROR", message, payload });
|
|
157
|
-
this.emailQueue.push(createTableString(this.buffer, error));
|
|
158
|
-
this.buffer.length = 0;
|
|
159
|
-
}
|
|
160
|
-
debug(message, payload) {
|
|
161
|
-
this.addToBuffer({ level: "DEBUG", message, payload });
|
|
162
|
-
}
|
|
163
|
-
async flush() {
|
|
164
|
-
for (const email of this.emailQueue) {
|
|
165
|
-
console.error(email);
|
|
166
|
-
}
|
|
167
|
-
this.buffer.length = 0;
|
|
168
|
-
this.emailQueue.length = 0;
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
function createTableString(events, error) {
|
|
172
|
-
if (events.length === 0) {
|
|
173
|
-
return "No events to display";
|
|
174
|
-
}
|
|
175
|
-
const dateWidth = Math.max(
|
|
176
|
-
4,
|
|
177
|
-
...events.map((e) => e.date.toISOString().length)
|
|
178
|
-
);
|
|
179
|
-
const levelWidth = Math.max(
|
|
180
|
-
5,
|
|
181
|
-
...events.map((e) => e.level.length)
|
|
182
|
-
);
|
|
183
|
-
const messageWidth = Math.max(7, ...events.map((e) => e.message.length));
|
|
184
|
-
const payloadWidth = Math.max(
|
|
185
|
-
7,
|
|
186
|
-
...events.map((e) => e.payload ? JSON.stringify(e.payload).length : 0)
|
|
187
|
-
);
|
|
188
|
-
const header = [
|
|
189
|
-
"DATE".padEnd(dateWidth),
|
|
190
|
-
"LEVEL".padEnd(levelWidth),
|
|
191
|
-
"MESSAGE".padEnd(messageWidth),
|
|
192
|
-
"PAYLOAD".padEnd(payloadWidth)
|
|
193
|
-
].join(" | ");
|
|
194
|
-
const separator = [
|
|
195
|
-
"-".repeat(dateWidth),
|
|
196
|
-
"-".repeat(levelWidth),
|
|
197
|
-
"-".repeat(messageWidth),
|
|
198
|
-
"-".repeat(payloadWidth)
|
|
199
|
-
].join("-|-");
|
|
200
|
-
const rows = events.map((event) => {
|
|
201
|
-
const date = event.date.toISOString().padEnd(dateWidth);
|
|
202
|
-
const level = event.level.padEnd(levelWidth);
|
|
203
|
-
const message = event.message.padEnd(messageWidth);
|
|
204
|
-
const payload = (event.payload ? JSON.stringify(event.payload) : "").padEnd(
|
|
205
|
-
payloadWidth
|
|
206
|
-
);
|
|
207
|
-
return [date, level, message, payload].join(" | ");
|
|
208
|
-
});
|
|
209
|
-
const errorSection = error ? "\n\nError Details:\n" + "-".repeat(20) + "\n" + (error instanceof Error ? `${error.name}: ${error.message}
|
|
210
|
-
${error.stack || ""}` : String(error)) : "";
|
|
211
|
-
return [header, separator, ...rows].join("\n") + errorSection;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// src/core/logger/di/loggerModule.ts
|
|
215
|
-
var LOGGER = new ServiceKey("Logger");
|
|
216
|
-
var LoggerFactory = singletonFactory({
|
|
217
|
-
provides: LOGGER,
|
|
218
|
-
dependsOn: [],
|
|
219
|
-
initialize: () => {
|
|
220
|
-
return Promise.resolve(new EmailAlertLogger(100, ["juanhr454@gmail.com"]));
|
|
221
|
-
}
|
|
222
14
|
});
|
|
223
|
-
|
|
224
|
-
// src/core/sms/di/smsModule.ts
|
|
225
|
-
var SMS_SERVICE = new ServiceKey("SmsService");
|
|
226
|
-
var SmsServiceFactory = singletonFactory({
|
|
227
|
-
provides: SMS_SERVICE,
|
|
228
|
-
dependsOn: [LOGGER],
|
|
229
|
-
initialize(logger) {
|
|
230
|
-
logger.info("Initializing SmsService");
|
|
231
|
-
if (import_node_process.default.env.environment === "dev") {
|
|
232
|
-
return Promise.resolve(new NoOpSmsService());
|
|
233
|
-
} else {
|
|
234
|
-
return Promise.resolve(new TigoSmsService());
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
var SmsServiceTestFactory = singletonFactory({
|
|
239
|
-
provides: SMS_SERVICE,
|
|
240
|
-
dependsOn: [],
|
|
241
|
-
initialize() {
|
|
242
|
-
return Promise.resolve(new NoOpSmsService());
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
// src/main.ts
|
|
247
|
-
var authModule = ServiceModule.from([SmsServiceFactory, LoggerFactory]);
|
|
248
|
-
function module2(module3, fn) {
|
|
249
|
-
return (event, context) => {
|
|
250
|
-
fn(event, { services: module3, ...context });
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
var handler = module2(authModule, login);
|
|
254
|
-
(async function() {
|
|
255
|
-
await deeplyNestedFunction({ services: authModule });
|
|
256
|
-
const logger = await authModule.inject(LOGGER);
|
|
257
|
-
if (logger instanceof EmailAlertLogger) {
|
|
258
|
-
await logger.flush();
|
|
259
|
-
}
|
|
260
|
-
console.log("Done");
|
|
261
|
-
})();
|
|
262
|
-
async function deeplyNestedFunction(context) {
|
|
263
|
-
await login({}, context);
|
|
264
|
-
}
|
|
265
|
-
async function login(event, context) {
|
|
266
|
-
const state = authorize(event);
|
|
267
|
-
const logger = await context.services.inject(LOGGER);
|
|
268
|
-
if (state === "DEVICE_CHANGED") {
|
|
269
|
-
logger.info("Device changed", { "user": "asad" });
|
|
270
|
-
const sms = await context.services.inject(SMS_SERVICE);
|
|
271
|
-
logger.debug("Sending sms");
|
|
272
|
-
try {
|
|
273
|
-
sms.send(971233149, "Hola Juan, tu pin es 22222");
|
|
274
|
-
} catch (e) {
|
|
275
|
-
logger.error("Error sending sms", e);
|
|
276
|
-
}
|
|
277
|
-
const sms1 = await context.services.inject(SMS_SERVICE);
|
|
278
|
-
}
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
function authorize(_request) {
|
|
282
|
-
return "DEVICE_CHANGED";
|
|
283
|
-
}
|
|
284
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2xpYi9zZXJ2aWNlTW9kdWxlLnRzIiwgIi4uL3NyYy9saWIvc2VydmljZUtleS50cyIsICIuLi9zcmMvbGliL3NlcnZpY2VGYWN0b3J5LnRzIiwgIi4uL3NyYy9jb3JlL3Ntcy9kaS9zbXNNb2R1bGUudHMiLCAiLi4vc3JjL2NvcmUvc21zL25vT3BTbXNTZXJ2aWNlLnRzIiwgIi4uL3NyYy9jb3JlL3Ntcy90aWdvU21zU2VydmljZS50cyIsICIuLi9zcmMvY29yZS9sb2dnZXIvZW1haWxBbGVydExvZ2dlci50cyIsICIuLi9zcmMvY29yZS9sb2dnZXIvZGkvbG9nZ2VyTW9kdWxlLnRzIiwgIi4uL3NyYy9tYWluLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBTZXJ2aWNlS2V5IH0gZnJvbSAnLi9zZXJ2aWNlS2V5JztcclxuaW1wb3J0IHsgU2VydmljZUZhY3RvcnkgfSBmcm9tICcuL3NlcnZpY2VGYWN0b3J5JztcclxuaW1wb3J0IHsgU2VydmljZVByb3ZpZGVyIH0gZnJvbSAnLi9zZXJ2aWNlUHJvdmlkZXInO1xyXG5cclxuZXhwb3J0IGNsYXNzIFNlcnZpY2VNb2R1bGUgaW1wbGVtZW50cyBTZXJ2aWNlUHJvdmlkZXIge1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgZmFjdG9yaWVzOiBTZXJ2aWNlRmFjdG9yeTxhbnksIGFueT5bXSA9IFtdO1xyXG5cclxuICBjb25zdHJ1Y3RvcihmYWN0b3JpZXM6IFNldDxTZXJ2aWNlRmFjdG9yeTx1bmtub3duLCBTZXJ2aWNlS2V5PHVua25vd24+W10+Pikge1xyXG4gICAgdGhpcy5mYWN0b3JpZXMgPSBBcnJheS5mcm9tKGZhY3Rvcmllcyk7XHJcbiAgICB0aGlzLmZhY3Rvcmllcy5mb3JFYWNoKChmYWN0b3J5KSA9PiB7XHJcbiAgICAgIGNoZWNrUmVjdXJzaXZlRGVwZW5kZW5jaWVzKGZhY3RvcnkpO1xyXG4gICAgICBjaGVja01pc3NpbmdEZXBlbmRlbmNpZXMoZmFjdG9yeSwgdGhpcy5mYWN0b3JpZXMpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYXN5bmMgaW5qZWN0PFQ+KGtleTogU2VydmljZUtleTxUPik6IFByb21pc2U8VD4ge1xyXG4gICAgY29uc3QgZmFjdG9yeSA9IHRoaXMuZmFjdG9yaWVzLmZpbmQoKGZhY3RvcnkpID0+IHtcclxuICAgICAgcmV0dXJuIGlzU3VpdGFibGUoa2V5LCBmYWN0b3J5KTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIENoZWNrIGlmIGEgZmFjdG9yeSB0byBzdXBwbHkgdGhlIHJlcXVlc3RlZCBrZXkgd2FzIG5vdCBmb3VuZFxyXG4gICAgaWYgKCFmYWN0b3J5KSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IGZpbmQgYSBzdWl0YWJsZSBmYWN0b3J5IGZvciAke2tleS5uYW1lfWApO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFJlc29sdmUgYWxsIGRlcGVuZGVuY2llcyBmaXJzdFxyXG4gICAgY29uc3QgZGVwZW5kZW5jaWVzID0gYXdhaXQgUHJvbWlzZS5hbGwoXHJcbiAgICAgIGZhY3RvcnkuZGVwZW5kc09uLm1hcCgoZGVwZW5kZW5jeUtleTogU2VydmljZUtleTx1bmtub3duPikgPT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmluamVjdChkZXBlbmRlbmN5S2V5KTtcclxuICAgICAgfSksXHJcbiAgICApO1xyXG5cclxuICAgIC8vIENhbGwgdGhlIGZhY3RvcnkgdG8gcmV0cmlldmUgdGhlIGRlcGVuZGVuY3lcclxuICAgIHJldHVybiBmYWN0b3J5LmluaXRpYWxpemUoLi4uZGVwZW5kZW5jaWVzKTtcclxuICB9XHJcblxyXG4gIHN0YXRpYyBmcm9tKFxyXG4gICAgZmFjdG9yaWVzOiBTZXJ2aWNlRmFjdG9yeTx1bmtub3duLCBTZXJ2aWNlS2V5PHVua25vd24+W10+W10sXHJcbiAgKTogU2VydmljZU1vZHVsZSB7XHJcbiAgICByZXR1cm4gbmV3IFNlcnZpY2VNb2R1bGUobmV3IFNldChmYWN0b3JpZXMpKTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNoZWNrUmVjdXJzaXZlRGVwZW5kZW5jaWVzKFxyXG4gIGZhY3Rvcnk6IFNlcnZpY2VGYWN0b3J5PHVua25vd24sIFNlcnZpY2VLZXk8dW5rbm93bj5bXT4sXHJcbikge1xyXG4gIGNvbnN0IHJlY3Vyc2l2ZSA9IGZhY3RvcnkuZGVwZW5kc09uLnNvbWUoKGRlcGVuZGVuY3lLZXkpID0+IHtcclxuICAgIHJldHVybiBkZXBlbmRlbmN5S2V5ID09PSBmYWN0b3J5LnByb3ZpZGVzO1xyXG4gIH0pO1xyXG5cclxuICBpZiAocmVjdXJzaXZlKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgICdSZWN1cnNpdmUgZGVwZW5kZW5jeSBkZXRlY3RlZCBvbjogJyArIGZhY3RvcnkucHJvdmlkZXMubmFtZSxcclxuICAgICk7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBjaGVja01pc3NpbmdEZXBlbmRlbmNpZXMoXHJcbiAgZmFjdG9yeTogU2VydmljZUZhY3Rvcnk8dW5rbm93biwgU2VydmljZUtleTx1bmtub3duPltdPixcclxuICBmYWN0b3JpZXM6IFNlcnZpY2VGYWN0b3J5PHVua25vd24+W10sXHJcbikge1xyXG4gIGNvbnN0IG1pc3NpbmdEZXBlbmRlbmNpZXMgPSBmYWN0b3J5LmRlcGVuZHNPbi5maWx0ZXIoXHJcbiAgICAoZGVwZW5kZW5jeUtleTogU2VydmljZUtleTxhbnk+KSA9PiB7XHJcbiAgICAgIHJldHVybiAhaXNSZWdpc3RlcmVkKGRlcGVuZGVuY3lLZXksIGZhY3Rvcmllcyk7XHJcbiAgICB9LFxyXG4gICk7XHJcbiAgaWYgKG1pc3NpbmdEZXBlbmRlbmNpZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBjb25zdCBkZXBlbmRlbmN5TGlzdCA9IG1pc3NpbmdEZXBlbmRlbmNpZXNcclxuICAgIC5tYXAoKGRlcGVuZGVuY3lLZXkpID0+IGAgLT4gJHtkZXBlbmRlbmN5S2V5Lm5hbWV9YClcclxuICAgIC5qb2luKCdcXG4nKTtcclxuICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICBgJHtmYWN0b3J5LnByb3ZpZGVzLm5hbWV9IHdpbGwgZmFpbCBiZWNhdXNlIGl0IGRlcGVuZHMgb246XFxuICR7ZGVwZW5kZW5jeUxpc3R9YCxcclxuICApO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc1JlZ2lzdGVyZWQoXHJcbiAga2V5OiBTZXJ2aWNlS2V5PHVua25vd24+LFxyXG4gIGZhY3RvcmllczogU2VydmljZUZhY3Rvcnk8dW5rbm93bj5bXSxcclxuKSB7XHJcbiAgcmV0dXJuIGZhY3Rvcmllcy5zb21lKChmYWN0b3J5KSA9PiBmYWN0b3J5LnByb3ZpZGVzID09PSBrZXkpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc1N1aXRhYmxlPFQsIEQgZXh0ZW5kcyBTZXJ2aWNlS2V5PHVua25vd24+W10+KFxyXG4gIGtleTogU2VydmljZUtleTxUPixcclxuICBmYWN0b3J5OiBTZXJ2aWNlRmFjdG9yeTx1bmtub3duLCBEPixcclxuKTogZmFjdG9yeSBpcyBTZXJ2aWNlRmFjdG9yeTxULCBEPiB7XHJcbiAgcmV0dXJuIGZhY3Rvcnk/LnByb3ZpZGVzID09PSBrZXk7XHJcbn1cclxuIiwgIi8vIEB0cy1pZ25vcmVcclxuZXhwb3J0IGNsYXNzIFNlcnZpY2VLZXk8VD4ge1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgc3ltYm9sOiBzeW1ib2w7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmcpIHtcclxuICAgIHRoaXMuc3ltYm9sID0gU3ltYm9sKG5hbWUpO1xyXG4gIH1cclxufVxyXG4iLCAiaW1wb3J0IHsgU2VydmljZUtleSB9IGZyb20gJy4vc2VydmljZUtleSc7XHJcblxyXG4vLyBIZWxwZXIgdHlwZXMgdG8gZXh0cmFjdCB0aGUgdHlwZSBmcm9tIFNlcnZpY2VLZXlcclxudHlwZSBTZXJ2aWNlVHlwZTxUPiA9IFQgZXh0ZW5kcyBTZXJ2aWNlS2V5PGluZmVyIFU+ID8gVSA6IG5ldmVyO1xyXG5cclxuLy8gSGVscGVyIHR5cGVzIHRvIGNvbnZlcnQgYW4gYXJyYXkgb2YgU2VydmljZUtleSB0byB0dXBsZSBvZiB0aGVpciB0eXBlc1xyXG50eXBlIERlcGVuZGVuY3lUeXBlczxUIGV4dGVuZHMgU2VydmljZUtleTx1bmtub3duPltdPiA9IHtcclxuICBbSyBpbiBrZXlvZiBUXTogU2VydmljZVR5cGU8VFtLXT47XHJcbn07XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFNlcnZpY2VGYWN0b3J5PFQsIEQgZXh0ZW5kcyBTZXJ2aWNlS2V5PHVua25vd24+W10gPSBbXT4ge1xyXG4gIHByb3ZpZGVzOiBTZXJ2aWNlS2V5PFQ+O1xyXG4gIGRlcGVuZHNPbjogRDtcclxuXHJcbiAgaW5pdGlhbGl6ZSguLi5kZXBlbmRlbmNpZXM6IERlcGVuZGVuY3lUeXBlczxEPik6IFByb21pc2U8VD47XHJcblxyXG4gIGRpc3Bvc2UoaW5zdGFuY2U6IFQpOiB2b2lkO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2luZ2xldG9uRmFjdG9yeTxULCBEIGV4dGVuZHMgU2VydmljZUtleTx1bmtub3duPltdID0gW10+KHtcclxuICBwcm92aWRlcyxcclxuICBkZXBlbmRzT24gPSBbXSBhcyB1bmtub3duIGFzIEQsXHJcbiAgaW5pdGlhbGl6ZSxcclxuICBkaXNwb3NlID0gKCkgPT4ge30sXHJcbn06IHtcclxuICBwcm92aWRlczogU2VydmljZUtleTxUPjtcclxuICBkZXBlbmRzT24/OiBEO1xyXG4gIGluaXRpYWxpemU6ICguLi5kZXBlbmRlbmNpZXM6IERlcGVuZGVuY3lUeXBlczxEPikgPT4gUHJvbWlzZTxUPjtcclxuICBkaXNwb3NlPzogKGluc3RhbmNlOiBUKSA9PiB2b2lkO1xyXG59KTogU2VydmljZUZhY3Rvcnk8VCwgRD4ge1xyXG4gIGxldCBpbnN0YW5jZTogVCB8IHVuZGVmaW5lZDtcclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIHByb3ZpZGVzLFxyXG4gICAgZGVwZW5kc09uLFxyXG4gICAgYXN5bmMgaW5pdGlhbGl6ZSguLi5kZXBlbmRlbmNpZXM6IERlcGVuZGVuY3lUeXBlczxEPik6IFByb21pc2U8VD4ge1xyXG4gICAgICBpZiAoaW5zdGFuY2UpIHtcclxuICAgICAgICByZXR1cm4gaW5zdGFuY2U7XHJcbiAgICAgIH1cclxuICAgICAgaW5zdGFuY2UgPSBhd2FpdCBpbml0aWFsaXplKC4uLmRlcGVuZGVuY2llcyk7XHJcbiAgICAgIHJldHVybiBpbnN0YW5jZTtcclxuICAgIH0sXHJcbiAgICBkaXNwb3NlKHNlcnZpY2VJbnN0YW5jZTogVCk6IHZvaWQge1xyXG4gICAgICBpZiAoaW5zdGFuY2UgPT09IHNlcnZpY2VJbnN0YW5jZSkge1xyXG4gICAgICAgIGRpc3Bvc2Uoc2VydmljZUluc3RhbmNlKTtcclxuICAgICAgICBpbnN0YW5jZSA9IHVuZGVmaW5lZDtcclxuICAgICAgfVxyXG4gICAgfSxcclxuICB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gb25lU2hvdEZhY3Rvcnk8VCwgRCBleHRlbmRzIFNlcnZpY2VLZXk8dW5rbm93bj5bXSA9IFtdPih7XHJcbiAgcHJvdmlkZXMsXHJcbiAgZGVwZW5kc09uLFxyXG4gIGluaXRpYWxpemUsXHJcbiAgZGlzcG9zZSA9ICgpID0+IHt9LFxyXG59OiB7XHJcbiAgcHJvdmlkZXM6IFNlcnZpY2VLZXk8VD47XHJcbiAgZGVwZW5kc09uOiBEO1xyXG4gIGluaXRpYWxpemU6ICguLi5kZXBlbmRlbmNpZXM6IERlcGVuZGVuY3lUeXBlczxEPikgPT4gUHJvbWlzZTxUPjtcclxuICBkaXNwb3NlPzogKGluc3RhbmNlOiBUKSA9PiB2b2lkO1xyXG59KTogU2VydmljZUZhY3Rvcnk8VCwgRD4ge1xyXG4gIHJldHVybiB7XHJcbiAgICBwcm92aWRlcyxcclxuICAgIGRlcGVuZHNPbixcclxuICAgIGluaXRpYWxpemUsXHJcbiAgICBkaXNwb3NlLFxyXG4gIH07XHJcbn1cclxuIiwgImltcG9ydCB7IFNlcnZpY2VLZXkgfSBmcm9tICcuLi8uLi8uLi9saWIvc2VydmljZUtleSc7XG5pbXBvcnQgeyBTbXNTZXJ2aWNlIH0gZnJvbSAnLi4vc21zU2VydmljZSc7XG5pbXBvcnQgeyBzaW5nbGV0b25GYWN0b3J5IH0gZnJvbSAnLi4vLi4vLi4vbGliL3NlcnZpY2VGYWN0b3J5JztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5pbXBvcnQgeyBOb09wU21zU2VydmljZSB9IGZyb20gJy4uL25vT3BTbXNTZXJ2aWNlJztcbmltcG9ydCB7IFRpZ29TbXNTZXJ2aWNlIH0gZnJvbSAnLi4vdGlnb1Ntc1NlcnZpY2UnO1xuaW1wb3J0IHsgTE9HR0VSIH0gZnJvbSAnLi4vLi4vbG9nZ2VyL2RpL2xvZ2dlck1vZHVsZSc7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi9sb2dnZXIvbG9nZ2VyJztcblxuZXhwb3J0IGNvbnN0IFNNU19TRVJWSUNFID0gbmV3IFNlcnZpY2VLZXk8U21zU2VydmljZT4oJ1Ntc1NlcnZpY2UnKTtcblxuZXhwb3J0IGNvbnN0IFNtc1NlcnZpY2VGYWN0b3J5ID0gc2luZ2xldG9uRmFjdG9yeSh7XG4gIHByb3ZpZGVzOiBTTVNfU0VSVklDRSxcbiAgZGVwZW5kc09uOiBbTE9HR0VSXSxcbiAgaW5pdGlhbGl6ZShsb2dnZXI6IExvZ2dlcik6IFByb21pc2U8U21zU2VydmljZT4ge1xuICAgIGxvZ2dlci5pbmZvKCdJbml0aWFsaXppbmcgU21zU2VydmljZScpO1xuICAgIC8vIFNpbmNlIHRoZSBjcmVhdGUgbWV0aG9kIGlzIGFzeW5jLCB3ZSBjb3VsZCBpbnN0YW50aWF0ZSBhIGRpZmZlcmVudFxuICAgIC8vIGltcGxlbWVudGF0aW9uIG9uIGRlbWFuZCBieSByZXRyaWV2aW5nIHNvbWUgY29uZmlndXJhdGlvbiBmcm9tIGEgZGJcbiAgICAvLyBvciBhIGNvbmZpZyBmaWxlLlxuICAgIGlmIChwcm9jZXNzLmVudi5lbnZpcm9ubWVudCA9PT0gJ2RldicpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IE5vT3BTbXNTZXJ2aWNlKCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBUaWdvU21zU2VydmljZSgpKTtcbiAgICB9XG4gIH0sXG59KTtcblxuZXhwb3J0IGNvbnN0IFNtc1NlcnZpY2VUZXN0RmFjdG9yeSA9IHNpbmdsZXRvbkZhY3Rvcnkoe1xuICBwcm92aWRlczogU01TX1NFUlZJQ0UsXG4gIGRlcGVuZHNPbjogW10sXG4gIGluaXRpYWxpemUoKTogUHJvbWlzZTxTbXNTZXJ2aWNlPiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXcgTm9PcFNtc1NlcnZpY2UoKSk7XG4gIH0sXG59KSIsICJpbXBvcnQgeyBTbXNTZXJ2aWNlIH0gZnJvbSAnLi9zbXNTZXJ2aWNlJztcclxuXHJcbmV4cG9ydCBjbGFzcyBOb09wU21zU2VydmljZSBpbXBsZW1lbnRzIFNtc1NlcnZpY2Uge1xyXG4gIHNlbmQocmVjaXBpZW50OiBudW1iZXIsIHRleHQ6IHN0cmluZykge1xyXG4gICAgY29uc29sZS53YXJuKGBOb09wU21zU2VydmljZTogU2VuZGluZyBzbXMgdG8gJHtyZWNpcGllbnR9OiAke3RleHR9YCk7XHJcbiAgfVxyXG59XHJcbiIsICJpbXBvcnQgeyBTbXNTZXJ2aWNlIH0gZnJvbSAnLi9zbXNTZXJ2aWNlJztcclxuXHJcbmV4cG9ydCBjbGFzcyBUaWdvU21zU2VydmljZSBpbXBsZW1lbnRzIFNtc1NlcnZpY2Uge1xyXG4gIHNlbmQoX3JlY2lwaWVudDogbnVtYmVyLCBfdGV4dDogc3RyaW5nKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCB5ZXQgaW1wbGVtZW50ZWQnKTtcclxuICB9XHJcbn1cclxuIiwgImltcG9ydCB7IExvZ2dlciwgTG9nRXZlbnQsIExvZ0V2ZW50UGF5bG9hZCB9IGZyb20gJy4vbG9nZ2VyJztcclxuXHJcbmV4cG9ydCBjbGFzcyBFbWFpbEFsZXJ0TG9nZ2VyIGltcGxlbWVudHMgTG9nZ2VyIHtcclxuICBwcml2YXRlIHJlYWRvbmx5IGJ1ZmZlcjogTG9nRXZlbnRbXSA9IFtdO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgYnVmZmVyU2l6ZTogbnVtYmVyO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVjaXBpZW50czogc3RyaW5nW107XHJcbiAgcHJpdmF0ZSByZWFkb25seSBlbWFpbFF1ZXVlOiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICBjb25zdHJ1Y3RvcihidWZmZXJTaXplOiBudW1iZXIgPSA1MCwgcmVjaXBpZW50czogc3RyaW5nW10gPSBbXSkge1xyXG4gICAgdGhpcy5idWZmZXJTaXplID0gYnVmZmVyU2l6ZTtcclxuICAgIHRoaXMucmVjaXBpZW50cyA9IHJlY2lwaWVudHM7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFkZFRvQnVmZmVyKGV2ZW50OiBPbWl0PExvZ0V2ZW50LCAnZGF0ZSc+KTogdm9pZCB7XHJcbiAgICAvLyBLZWVwIHRoZSBidWZmZXIgdG8gdGhlIHNwZWNpZmllZCBzaXplXHJcbiAgICBpZiAodGhpcy5idWZmZXIubGVuZ3RoID49IHRoaXMuYnVmZmVyU2l6ZSkge1xyXG4gICAgICB0aGlzLmJ1ZmZlci5zaGlmdCgpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5idWZmZXIucHVzaCh7IC4uLmV2ZW50LCBkYXRlOiBuZXcgRGF0ZSgpIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGluZm8obWVzc2FnZTogc3RyaW5nLCBwYXlsb2FkPzogTG9nRXZlbnRQYXlsb2FkKTogdm9pZCB7XHJcbiAgICB0aGlzLmFkZFRvQnVmZmVyKHsgbGV2ZWw6ICdJTkZPJywgbWVzc2FnZSwgcGF5bG9hZCB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBlcnJvcihcclxuICAgIG1lc3NhZ2U6IHN0cmluZyxcclxuICAgIGVycm9yPzogdW5rbm93bixcclxuICAgIHBheWxvYWQ/OiBMb2dFdmVudFBheWxvYWQsXHJcbiAgKTogdm9pZCB7XHJcbiAgICB0aGlzLmFkZFRvQnVmZmVyKHsgbGV2ZWw6ICdFUlJPUicsIG1lc3NhZ2UsIHBheWxvYWQgfSk7XHJcbiAgICB0aGlzLmVtYWlsUXVldWUucHVzaChjcmVhdGVUYWJsZVN0cmluZyh0aGlzLmJ1ZmZlciwgZXJyb3IpKTtcclxuICAgIHRoaXMuYnVmZmVyLmxlbmd0aCA9IDA7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZGVidWcobWVzc2FnZTogc3RyaW5nLCBwYXlsb2FkPzogTG9nRXZlbnRQYXlsb2FkKTogdm9pZCB7XHJcbiAgICB0aGlzLmFkZFRvQnVmZmVyKHsgbGV2ZWw6ICdERUJVRycsIG1lc3NhZ2UsIHBheWxvYWQgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYXN5bmMgZmx1c2goKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBmb3IgKGNvbnN0IGVtYWlsIG9mIHRoaXMuZW1haWxRdWV1ZSkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGVtYWlsKTtcclxuICAgIH1cclxuICAgIC8vIENsZWFyIGFsbCBidWZmZXJzXHJcbiAgICB0aGlzLmJ1ZmZlci5sZW5ndGggPSAwO1xyXG4gICAgdGhpcy5lbWFpbFF1ZXVlLmxlbmd0aCA9IDA7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVUYWJsZVN0cmluZyhldmVudHM6IExvZ0V2ZW50W10sIGVycm9yPzogdW5rbm93bik6IHN0cmluZyB7XHJcbiAgaWYgKGV2ZW50cy5sZW5ndGggPT09IDApIHtcclxuICAgIHJldHVybiAnTm8gZXZlbnRzIHRvIGRpc3BsYXknO1xyXG4gIH1cclxuXHJcbiAgLy8gQ2FsY3VsYXRlIGNvbHVtbiB3aWR0aHNcclxuICBjb25zdCBkYXRlV2lkdGggPSBNYXRoLm1heChcclxuICAgIDQsXHJcbiAgICAuLi5ldmVudHMubWFwKChlKSA9PiBlLmRhdGUudG9JU09TdHJpbmcoKS5sZW5ndGgpLFxyXG4gICk7XHJcbiAgY29uc3QgbGV2ZWxXaWR0aCA9IE1hdGgubWF4KFxyXG4gICAgNSwgLy8gXCJMZXZlbFwiIGhlYWRlciBsZW5ndGhcclxuICAgIC4uLmV2ZW50cy5tYXAoKGUpID0+IGUubGV2ZWwubGVuZ3RoKSxcclxuICApO1xyXG4gIGNvbnN0IG1lc3NhZ2VXaWR0aCA9IE1hdGgubWF4KDcsIC4uLmV2ZW50cy5tYXAoKGUpID0+IGUubWVzc2FnZS5sZW5ndGgpKTtcclxuICBjb25zdCBwYXlsb2FkV2lkdGggPSBNYXRoLm1heChcclxuICAgIDcsXHJcbiAgICAuLi5ldmVudHMubWFwKChlKSA9PiAoZS5wYXlsb2FkID8gSlNPTi5zdHJpbmdpZnkoZS5wYXlsb2FkKS5sZW5ndGggOiAwKSksXHJcbiAgKTtcclxuXHJcbiAgLy8gQ3JlYXRlIGhlYWRlclxyXG4gIGNvbnN0IGhlYWRlciA9IFtcclxuICAgICdEQVRFJy5wYWRFbmQoZGF0ZVdpZHRoKSxcclxuICAgICdMRVZFTCcucGFkRW5kKGxldmVsV2lkdGgpLFxyXG4gICAgJ01FU1NBR0UnLnBhZEVuZChtZXNzYWdlV2lkdGgpLFxyXG4gICAgJ1BBWUxPQUQnLnBhZEVuZChwYXlsb2FkV2lkdGgpLFxyXG4gIF0uam9pbignIHwgJyk7XHJcblxyXG4gIC8vIENyZWF0ZSBzZXBhcmF0b3JcclxuICBjb25zdCBzZXBhcmF0b3IgPSBbXHJcbiAgICAnLScucmVwZWF0KGRhdGVXaWR0aCksXHJcbiAgICAnLScucmVwZWF0KGxldmVsV2lkdGgpLFxyXG4gICAgJy0nLnJlcGVhdChtZXNzYWdlV2lkdGgpLFxyXG4gICAgJy0nLnJlcGVhdChwYXlsb2FkV2lkdGgpLFxyXG4gIF0uam9pbignLXwtJyk7XHJcblxyXG4gIC8vIENyZWF0ZSByb3dzXHJcbiAgY29uc3Qgcm93cyA9IGV2ZW50cy5tYXAoKGV2ZW50KSA9PiB7XHJcbiAgICBjb25zdCBkYXRlID0gZXZlbnQuZGF0ZS50b0lTT1N0cmluZygpLnBhZEVuZChkYXRlV2lkdGgpO1xyXG4gICAgY29uc3QgbGV2ZWwgPSBldmVudC5sZXZlbC5wYWRFbmQobGV2ZWxXaWR0aCk7XHJcbiAgICBjb25zdCBtZXNzYWdlID0gZXZlbnQubWVzc2FnZS5wYWRFbmQobWVzc2FnZVdpZHRoKTtcclxuICAgIGNvbnN0IHBheWxvYWQgPSAoZXZlbnQucGF5bG9hZCA/IEpTT04uc3RyaW5naWZ5KGV2ZW50LnBheWxvYWQpIDogJycpLnBhZEVuZChcclxuICAgICAgcGF5bG9hZFdpZHRoLFxyXG4gICAgKTtcclxuICAgIHJldHVybiBbZGF0ZSwgbGV2ZWwsIG1lc3NhZ2UsIHBheWxvYWRdLmpvaW4oJyB8ICcpO1xyXG4gIH0pO1xyXG5cclxuICAvLyBDcmVhdGUgZXJyb3Igc2VjdGlvbiBpZiBlcnJvciBleGlzdHNcclxuICBjb25zdCBlcnJvclNlY3Rpb24gPSBlcnJvclxyXG4gICAgPyAnXFxuXFxuRXJyb3IgRGV0YWlsczpcXG4nICtcclxuICAgICAgJy0nLnJlcGVhdCgyMCkgK1xyXG4gICAgICAnXFxuJyArXHJcbiAgICAgIChlcnJvciBpbnN0YW5jZW9mIEVycm9yXHJcbiAgICAgICAgPyBgJHtlcnJvci5uYW1lfTogJHtlcnJvci5tZXNzYWdlfVxcbiR7ZXJyb3Iuc3RhY2sgfHwgJyd9YFxyXG4gICAgICAgIDogU3RyaW5nKGVycm9yKSlcclxuICAgIDogJyc7XHJcblxyXG4gIC8vIENvbWJpbmUgYWxsIHBhcnRzXHJcbiAgcmV0dXJuIFtoZWFkZXIsIHNlcGFyYXRvciwgLi4ucm93c10uam9pbignXFxuJykgKyBlcnJvclNlY3Rpb247XHJcbn1cclxuIiwgImltcG9ydCB7IHNpbmdsZXRvbkZhY3RvcnkgfSBmcm9tICcuLi8uLi8uLi9saWIvc2VydmljZUZhY3RvcnknO1xyXG5pbXBvcnQgeyBTZXJ2aWNlS2V5IH0gZnJvbSAnLi4vLi4vLi4vbGliL3NlcnZpY2VLZXknO1xyXG5pbXBvcnQgeyBFbWFpbEFsZXJ0TG9nZ2VyIH0gZnJvbSAnLi4vZW1haWxBbGVydExvZ2dlcic7XHJcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4uL2xvZ2dlcic7XHJcbmltcG9ydCB7IFNNU19TRVJWSUNFIH0gZnJvbSAnLi4vLi4vc21zL2RpL3Ntc01vZHVsZSc7XHJcbmltcG9ydCB7IFNtc1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zbXMvc21zU2VydmljZSc7XHJcblxyXG5leHBvcnQgY29uc3QgTE9HR0VSID0gbmV3IFNlcnZpY2VLZXk8TG9nZ2VyPignTG9nZ2VyJyk7XHJcblxyXG5leHBvcnQgY29uc3QgTG9nZ2VyRmFjdG9yeSA9IHNpbmdsZXRvbkZhY3Rvcnkoe1xyXG4gIHByb3ZpZGVzOiBMT0dHRVIsXHJcbiAgZGVwZW5kc09uOiBbXSxcclxuICBpbml0aWFsaXplOiAoKSA9PiB7XHJcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBFbWFpbEFsZXJ0TG9nZ2VyKDEwMCwgWydqdWFuaHI0NTRAZ21haWwuY29tJ10pKTtcclxuICB9LFxyXG59KTtcclxuIiwgImltcG9ydCB7IFNlcnZpY2VNb2R1bGUgfSBmcm9tICcuL2xpYi9zZXJ2aWNlTW9kdWxlJztcclxuaW1wb3J0IHsgU2VydmljZVByb3ZpZGVyIH0gZnJvbSAnLi9saWIvc2VydmljZVByb3ZpZGVyJztcclxuaW1wb3J0IHsgU01TX1NFUlZJQ0UsIFNtc1NlcnZpY2VGYWN0b3J5IH0gZnJvbSAnLi9jb3JlL3Ntcy9kaS9zbXNNb2R1bGUnO1xyXG5pbXBvcnQgeyBMT0dHRVIsIExvZ2dlckZhY3RvcnkgfSBmcm9tICcuL2NvcmUvbG9nZ2VyL2RpL2xvZ2dlck1vZHVsZSc7XHJcbmltcG9ydCB7IEVtYWlsQWxlcnRMb2dnZXIgfSBmcm9tICcuL2NvcmUvbG9nZ2VyL2VtYWlsQWxlcnRMb2dnZXInO1xyXG5cclxuY29uc3QgYXV0aE1vZHVsZSA9IFNlcnZpY2VNb2R1bGUuZnJvbShbU21zU2VydmljZUZhY3RvcnksIExvZ2dlckZhY3RvcnldKTtcclxuXHJcbmZ1bmN0aW9uIG1vZHVsZShcclxuICBtb2R1bGU6IFNlcnZpY2VNb2R1bGUsXHJcbiAgZm46IChldmVudDogb2JqZWN0LCBjb250ZXh0OiBDb250ZXh0KSA9PiB2b2lkLFxyXG4pIHtcclxuICByZXR1cm4gKGV2ZW50OiBvYmplY3QsIGNvbnRleHQ6IG9iamVjdCkgPT4ge1xyXG4gICAgZm4oZXZlbnQsIHsgc2VydmljZXM6IG1vZHVsZSwgLi4uY29udGV4dCB9KTtcclxuICB9O1xyXG59XHJcblxyXG5jb25zdCBoYW5kbGVyID0gbW9kdWxlKGF1dGhNb2R1bGUsIGxvZ2luKTtcclxuXHJcbihhc3luYyBmdW5jdGlvbiAoKSB7XHJcbiAgYXdhaXQgZGVlcGx5TmVzdGVkRnVuY3Rpb24oeyBzZXJ2aWNlczogYXV0aE1vZHVsZSB9KTtcclxuICBjb25zdCBsb2dnZXIgPSBhd2FpdCBhdXRoTW9kdWxlLmluamVjdChMT0dHRVIpO1xyXG4gIGlmIChsb2dnZXIgaW5zdGFuY2VvZiBFbWFpbEFsZXJ0TG9nZ2VyKSB7XHJcbiAgICBhd2FpdCBsb2dnZXIuZmx1c2goKTtcclxuICB9XHJcbiAgY29uc29sZS5sb2coJ0RvbmUnKTtcclxufSkoKTtcclxuXHJcbmFzeW5jIGZ1bmN0aW9uIGRlZXBseU5lc3RlZEZ1bmN0aW9uKGNvbnRleHQ6IENvbnRleHQpIHtcclxuICBhd2FpdCBsb2dpbih7fSwgY29udGV4dCk7XHJcbn1cclxuXHJcbmludGVyZmFjZSBDb250ZXh0IHtcclxuICBzZXJ2aWNlczogU2VydmljZVByb3ZpZGVyO1xyXG59XHJcblxyXG5hc3luYyBmdW5jdGlvbiBsb2dpbihldmVudDogYW55LCBjb250ZXh0OiBDb250ZXh0KSB7XHJcbiAgY29uc3Qgc3RhdGUgPSBhdXRob3JpemUoZXZlbnQpO1xyXG4gIGNvbnN0IGxvZ2dlciA9IGF3YWl0IGNvbnRleHQuc2VydmljZXMuaW5qZWN0KExPR0dFUik7XHJcbiAgaWYgKHN0YXRlID09PSAnREVWSUNFX0NIQU5HRUQnKSB7XHJcbiAgICBsb2dnZXIuaW5mbygnRGV2aWNlIGNoYW5nZWQnLCB7J3VzZXInOiAnYXNhZCd9KTtcclxuICAgIC8vIFdpdGggdGhlIHNlcnZpY2Uga2V5IHdlIGdldCB0eXBlIHNhZmV0eS9pbmZlcmVuY2UgYW5kIG5hdmlnYXRlIHRvIGRlZmluaXRpb24gZm9yIGZyZWUsXHJcbiAgICAvLyB0aGVyZSBpcyBubyBtYWdpYyBubyBhbm5vdGF0aW9ucywgd2UgY2FuIHNlZSBhbGwgdGhlXHJcbiAgICAvLyBmYWN0b3JpZXMgdGhhdCBwcm92aWRlIHRoaXMgZGVwZW5kZW5jeSBhbmQgc2VlIGFsbCBwbGFjZXMgd2hlcmUgdGhpcyBpcyByZXRyaWV2ZWQuXHJcbiAgICBjb25zdCBzbXMgPSBhd2FpdCBjb250ZXh0LnNlcnZpY2VzLmluamVjdChTTVNfU0VSVklDRSk7XHJcbiAgICBsb2dnZXIuZGVidWcoJ1NlbmRpbmcgc21zJyk7XHJcbiAgICB0cnkge1xyXG4gICAgICBzbXMuc2VuZCg5NzEyMzMxNDksICdIb2xhIEp1YW4sIHR1IHBpbiBlcyAyMjIyMicpO1xyXG4gICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgc21zJywgZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmV0cmlldmluZyB0aGUgc2VydmljZSBhIHNlY29uZCB0aW1lIHdvdWxkIGhhdmUgdmlydHVhbGx5IHplcm8gY29zdCBpZiB0aGVcclxuICAgIC8vIHVuZGVybHlpbmcgZmFjdG9yeSBwcm92aWRlcyBhIHNpbmdsZXRvbi5cclxuICAgIGNvbnN0IHNtczEgPSBhd2FpdCBjb250ZXh0LnNlcnZpY2VzLmluamVjdChTTVNfU0VSVklDRSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm47XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGF1dGhvcml6ZShfcmVxdWVzdDogYW55KTogJ09LJyB8ICdERVZJQ0VfQ0hBTkdFRCcge1xyXG4gIHJldHVybiAnREVWSUNFX0NIQU5HRUQnO1xyXG59XHJcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFJTyxJQUFNLGdCQUFOLE1BQU0sZUFBeUM7QUFBQSxFQUdwRCxZQUFZLFdBQWdFO0FBRjVFLFNBQWlCLFlBQXdDLENBQUM7QUFH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
|
|
15
|
+
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;AAAA,6CAA0C;AAC1C,qDAAoD;AAEpD,MAAM,gBAAgB,GAAG,IAAI,uBAAU,CAAc,aAAa,CAAC,CAAC;AACpE,MAAM,OAAO,GAAG,IAAI,uBAAU,CAAS,KAAK,CAAC,CAAC;AAC9C,MAAM,OAAO,GAAG,IAAI,uBAAU,CAAS,KAAK,CAAC,CAAC;AAO9C,MAAM,kBAAkB,GAAG,IAAA,iCAAgB,EAAC;IAC1C,QAAQ,EAAE,gBAAgB;IAC1B,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,CAAU;IACtC,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACvB,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACtB,CAAC;CACF,CAAC,CAAC"}
|
package/dist/serviceFactory.d.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { ServiceKey } from './serviceKey';
|
|
2
2
|
type ServiceType<T> = T extends ServiceKey<infer U> ? U : never;
|
|
3
|
-
type DependencyTypes<T extends ServiceKey<unknown>[]> = {
|
|
3
|
+
type DependencyTypes<T extends readonly ServiceKey<unknown>[]> = {
|
|
4
4
|
[K in keyof T]: ServiceType<T[K]>;
|
|
5
5
|
};
|
|
6
|
-
export interface ServiceFactory<T, D extends ServiceKey<unknown>[] = []> {
|
|
6
|
+
export interface ServiceFactory<T, D extends readonly ServiceKey<unknown>[] = []> {
|
|
7
7
|
provides: ServiceKey<T>;
|
|
8
8
|
dependsOn: D;
|
|
9
|
-
initialize(...dependencies: DependencyTypes<D>): Promise<T>;
|
|
9
|
+
initialize(...dependencies: DependencyTypes<D>): T | Promise<T>;
|
|
10
10
|
dispose(instance: T): void;
|
|
11
11
|
}
|
|
12
|
-
export declare function singletonFactory<T, D extends ServiceKey<unknown>[] = []>({ provides, dependsOn, initialize, dispose, }: {
|
|
12
|
+
export declare function singletonFactory<T, D extends readonly ServiceKey<unknown>[] = []>({ provides, dependsOn, initialize, dispose, }: {
|
|
13
13
|
provides: ServiceKey<T>;
|
|
14
14
|
dependsOn?: D;
|
|
15
|
-
initialize: (...dependencies: DependencyTypes<D>) => Promise<T>;
|
|
15
|
+
initialize: (...dependencies: DependencyTypes<D>) => T | Promise<T>;
|
|
16
16
|
dispose?: (instance: T) => void;
|
|
17
17
|
}): ServiceFactory<T, D>;
|
|
18
|
-
export declare function oneShotFactory<T, D extends ServiceKey<unknown>[] = []>({ provides, dependsOn, initialize, dispose, }: {
|
|
18
|
+
export declare function oneShotFactory<T, D extends readonly ServiceKey<unknown>[] = []>({ provides, dependsOn, initialize, dispose, }: {
|
|
19
19
|
provides: ServiceKey<T>;
|
|
20
20
|
dependsOn: D;
|
|
21
|
-
initialize: (...dependencies: DependencyTypes<D>) => Promise<T>;
|
|
21
|
+
initialize: (...dependencies: DependencyTypes<D>) => T | Promise<T>;
|
|
22
22
|
dispose?: (instance: T) => void;
|
|
23
23
|
}): ServiceFactory<T, D>;
|
|
24
24
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceFactory.d.ts","sourceRoot":"","sources":["../src/serviceFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAGhE,KAAK,eAAe,CAAC,CAAC,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"serviceFactory.d.ts","sourceRoot":"","sources":["../src/serviceFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAGhE,KAAK,eAAe,CAAC,CAAC,SAAS,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI;KAC9D,CAAC,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,WAAW,cAAc,CAC7B,CAAC,EACD,CAAC,SAAS,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE;IAE7C,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IACxB,SAAS,EAAE,CAAC,CAAC;IAEb,UAAU,CAAC,GAAG,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAEhE,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,CAC9B,CAAC,EACD,CAAC,SAAS,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,EAC7C,EACA,QAAQ,EACR,SAA8B,EAC9B,UAAU,EACV,OAAkB,GACnB,EAAE;IACD,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IACxB,SAAS,CAAC,EAAE,CAAC,CAAC;IACd,UAAU,EAAE,CAAC,GAAG,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,IAAI,CAAC;CACjC,GAAG,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAoBvB;AAED,wBAAgB,cAAc,CAC5B,CAAC,EACD,CAAC,SAAS,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,EAC7C,EACA,QAAQ,EACR,SAAS,EACT,UAAU,EACV,OAAkB,GACnB,EAAE;IACD,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IACxB,SAAS,EAAE,CAAC,CAAC;IACb,UAAU,EAAE,CAAC,GAAG,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,IAAI,CAAC;CACjC,GAAG,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAOvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceFactory.js","sourceRoot":"","sources":["../src/serviceFactory.ts"],"names":[],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"serviceFactory.js","sourceRoot":"","sources":["../src/serviceFactory.ts"],"names":[],"mappings":";;;;;;;;;;;AAsBA,4CAiCC;AAED,wCAoBC;AAvDD,SAAgB,gBAAgB,CAG9B,EACA,QAAQ,EACR,SAAS,GAAG,EAAkB,EAC9B,UAAU,EACV,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,GAMnB;IACC,IAAI,QAAuB,CAAC;IAE5B,OAAO;QACL,QAAQ;QACR,SAAS;QACH,UAAU,CAAC,GAAG,YAAgC;;gBAClD,IAAI,QAAQ,EAAE,CAAC;oBACb,OAAO,QAAQ,CAAC;gBAClB,CAAC;gBACD,QAAQ,GAAG,MAAM,UAAU,CAAC,GAAG,YAAY,CAAC,CAAC;gBAC7C,OAAO,QAAQ,CAAC;YAClB,CAAC;SAAA;QACD,OAAO,CAAC,eAAkB;YACxB,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;gBACjC,OAAO,CAAC,eAAe,CAAC,CAAC;gBACzB,QAAQ,GAAG,SAAS,CAAC;YACvB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAgB,cAAc,CAG5B,EACA,QAAQ,EACR,SAAS,EACT,UAAU,EACV,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,GAMnB;IACC,OAAO;QACL,QAAQ;QACR,SAAS;QACT,UAAU;QACV,OAAO;KACR,CAAC;AACJ,CAAC"}
|
package/dist/serviceModule.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { ServiceFactory } from './serviceFactory';
|
|
|
3
3
|
import { ServiceProvider } from './serviceProvider';
|
|
4
4
|
export declare class ServiceModule implements ServiceProvider {
|
|
5
5
|
private readonly factories;
|
|
6
|
-
constructor(factories: Set<ServiceFactory<unknown, ServiceKey<unknown>[]>>);
|
|
6
|
+
constructor(factories: Set<ServiceFactory<unknown, readonly ServiceKey<unknown>[]>>);
|
|
7
7
|
get<T>(key: ServiceKey<T>): Promise<T>;
|
|
8
|
-
static from(entries: (ServiceModule | ServiceFactory<unknown, ServiceKey<unknown>[]>)[]): ServiceModule;
|
|
8
|
+
static from(entries: (ServiceModule | ServiceFactory<unknown, readonly ServiceKey<unknown>[]>)[]): ServiceModule;
|
|
9
9
|
}
|
|
10
10
|
//# sourceMappingURL=serviceModule.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceModule.d.ts","sourceRoot":"","sources":["../src/serviceModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,aAAc,YAAW,eAAe;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkC;
|
|
1
|
+
{"version":3,"file":"serviceModule.d.ts","sourceRoot":"","sources":["../src/serviceModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,aAAc,YAAW,eAAe;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkC;gBAG1D,SAAS,EAAE,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAS5D,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBnD,MAAM,CAAC,IAAI,CACT,OAAO,EAAE,CAAC,aAAa,GAAG,cAAc,CAAC,OAAO,EAAE,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,GACnF,aAAa;CAajB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceModule.js","sourceRoot":"","sources":["../src/serviceModule.ts"],"names":[],"mappings":";;;;;;;;;;;;AAIA,MAAa,aAAa;IAGxB,
|
|
1
|
+
{"version":3,"file":"serviceModule.js","sourceRoot":"","sources":["../src/serviceModule.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/main.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ServiceKey } from './serviceKey';
|
|
2
|
+
import { singletonFactory } from './serviceFactory';
|
|
3
|
+
|
|
4
|
+
const TEST_SERVICE_KEY = new ServiceKey<TestService>('testService');
|
|
5
|
+
const FOO_KEY = new ServiceKey<string>('foo');
|
|
6
|
+
const BAR_KEY = new ServiceKey<number>('bar');
|
|
7
|
+
|
|
8
|
+
interface TestService {
|
|
9
|
+
foo: string;
|
|
10
|
+
bar: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const TestServiceFactory = singletonFactory({
|
|
14
|
+
provides: TEST_SERVICE_KEY,
|
|
15
|
+
dependsOn: [FOO_KEY, BAR_KEY] as const,
|
|
16
|
+
initialize: (foo, bar) => {
|
|
17
|
+
return { foo, bar };
|
|
18
|
+
},
|
|
19
|
+
});
|
package/src/serviceFactory.ts
CHANGED
|
@@ -1,69 +1,78 @@
|
|
|
1
|
-
import { ServiceKey } from './serviceKey';
|
|
2
|
-
|
|
3
|
-
// Helper types to extract the type from ServiceKey
|
|
4
|
-
type ServiceType<T> = T extends ServiceKey<infer U> ? U : never;
|
|
5
|
-
|
|
6
|
-
// Helper types to convert an array of ServiceKey to tuple of their types
|
|
7
|
-
type DependencyTypes<T extends ServiceKey<unknown>[]> = {
|
|
8
|
-
[K in keyof T]: ServiceType<T[K]>;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export interface ServiceFactory<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
1
|
+
import { ServiceKey } from './serviceKey';
|
|
2
|
+
|
|
3
|
+
// Helper types to extract the type from ServiceKey
|
|
4
|
+
type ServiceType<T> = T extends ServiceKey<infer U> ? U : never;
|
|
5
|
+
|
|
6
|
+
// Helper types to convert an array/tuple of ServiceKey to tuple of their types
|
|
7
|
+
type DependencyTypes<T extends readonly ServiceKey<unknown>[]> = {
|
|
8
|
+
[K in keyof T]: ServiceType<T[K]>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export interface ServiceFactory<
|
|
12
|
+
T,
|
|
13
|
+
D extends readonly ServiceKey<unknown>[] = [],
|
|
14
|
+
> {
|
|
15
|
+
provides: ServiceKey<T>;
|
|
16
|
+
dependsOn: D;
|
|
17
|
+
|
|
18
|
+
initialize(...dependencies: DependencyTypes<D>): T | Promise<T>;
|
|
19
|
+
|
|
20
|
+
dispose(instance: T): void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function singletonFactory<
|
|
24
|
+
T,
|
|
25
|
+
D extends readonly ServiceKey<unknown>[] = [],
|
|
26
|
+
>({
|
|
27
|
+
provides,
|
|
28
|
+
dependsOn = [] as unknown as D,
|
|
29
|
+
initialize,
|
|
30
|
+
dispose = () => {},
|
|
31
|
+
}: {
|
|
32
|
+
provides: ServiceKey<T>;
|
|
33
|
+
dependsOn?: D;
|
|
34
|
+
initialize: (...dependencies: DependencyTypes<D>) => T | Promise<T>;
|
|
35
|
+
dispose?: (instance: T) => void;
|
|
36
|
+
}): ServiceFactory<T, D> {
|
|
37
|
+
let instance: T | undefined;
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
provides,
|
|
41
|
+
dependsOn,
|
|
42
|
+
async initialize(...dependencies: DependencyTypes<D>): Promise<T> {
|
|
43
|
+
if (instance) {
|
|
44
|
+
return instance;
|
|
45
|
+
}
|
|
46
|
+
instance = await initialize(...dependencies);
|
|
47
|
+
return instance;
|
|
48
|
+
},
|
|
49
|
+
dispose(serviceInstance: T): void {
|
|
50
|
+
if (instance === serviceInstance) {
|
|
51
|
+
dispose(serviceInstance);
|
|
52
|
+
instance = undefined;
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function oneShotFactory<
|
|
59
|
+
T,
|
|
60
|
+
D extends readonly ServiceKey<unknown>[] = [],
|
|
61
|
+
>({
|
|
62
|
+
provides,
|
|
63
|
+
dependsOn,
|
|
64
|
+
initialize,
|
|
65
|
+
dispose = () => {},
|
|
66
|
+
}: {
|
|
67
|
+
provides: ServiceKey<T>;
|
|
68
|
+
dependsOn: D;
|
|
69
|
+
initialize: (...dependencies: DependencyTypes<D>) => T | Promise<T>;
|
|
70
|
+
dispose?: (instance: T) => void;
|
|
71
|
+
}): ServiceFactory<T, D> {
|
|
72
|
+
return {
|
|
73
|
+
provides,
|
|
74
|
+
dependsOn,
|
|
75
|
+
initialize,
|
|
76
|
+
dispose,
|
|
77
|
+
};
|
|
78
|
+
}
|
package/src/serviceModule.ts
CHANGED
|
@@ -5,7 +5,9 @@ import { ServiceProvider } from './serviceProvider';
|
|
|
5
5
|
export class ServiceModule implements ServiceProvider {
|
|
6
6
|
private readonly factories: ServiceFactory<any, any>[] = [];
|
|
7
7
|
|
|
8
|
-
constructor(
|
|
8
|
+
constructor(
|
|
9
|
+
factories: Set<ServiceFactory<unknown, readonly ServiceKey<unknown>[]>>,
|
|
10
|
+
) {
|
|
9
11
|
this.factories = Array.from(factories);
|
|
10
12
|
this.factories.forEach((factory) => {
|
|
11
13
|
checkRecursiveDependencies(factory);
|
|
@@ -35,7 +37,7 @@ export class ServiceModule implements ServiceProvider {
|
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
static from(
|
|
38
|
-
entries: (ServiceModule | ServiceFactory<unknown, ServiceKey<unknown>[]>)[],
|
|
40
|
+
entries: (ServiceModule | ServiceFactory<unknown, readonly ServiceKey<unknown>[]>)[],
|
|
39
41
|
): ServiceModule {
|
|
40
42
|
return new ServiceModule(
|
|
41
43
|
new Set(
|
|
@@ -52,7 +54,7 @@ export class ServiceModule implements ServiceProvider {
|
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
function checkRecursiveDependencies(
|
|
55
|
-
factory: ServiceFactory<unknown, ServiceKey<unknown>[]>,
|
|
57
|
+
factory: ServiceFactory<unknown, readonly ServiceKey<unknown>[]>,
|
|
56
58
|
) {
|
|
57
59
|
const recursive = factory.dependsOn.some((dependencyKey) => {
|
|
58
60
|
return dependencyKey === factory.provides;
|
|
@@ -66,7 +68,7 @@ function checkRecursiveDependencies(
|
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
function checkMissingDependencies(
|
|
69
|
-
factory: ServiceFactory<unknown, ServiceKey<unknown>[]>,
|
|
71
|
+
factory: ServiceFactory<unknown, readonly ServiceKey<unknown>[]>,
|
|
70
72
|
factories: ServiceFactory<unknown>[],
|
|
71
73
|
) {
|
|
72
74
|
const missingDependencies = factory.dependsOn.filter(
|
|
@@ -93,7 +95,7 @@ function isRegistered(
|
|
|
93
95
|
return factories.some((factory) => factory.provides === key);
|
|
94
96
|
}
|
|
95
97
|
|
|
96
|
-
function isSuitable<T, D extends ServiceKey<unknown>[]>(
|
|
98
|
+
function isSuitable<T, D extends readonly ServiceKey<unknown>[]>(
|
|
97
99
|
key: ServiceKey<T>,
|
|
98
100
|
factory: ServiceFactory<unknown, D>,
|
|
99
101
|
): factory is ServiceFactory<T, D> {
|