@foxford/den 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.mdx +9 -0
- package/adapter.cjs +43 -0
- package/adapter.d.cts +73 -0
- package/adapter.d.ts +73 -0
- package/adapter.mjs +17 -0
- package/define-slot--HM6B232.d.ts +500 -0
- package/define-slot-es1K6_-L.d.cts +500 -0
- package/define.cjs +282 -0
- package/define.d.cts +26 -0
- package/define.d.ts +26 -0
- package/define.mjs +247 -0
- package/index.cjs +1027 -0
- package/index.d.cts +386 -0
- package/index.d.ts +386 -0
- package/index.mjs +975 -0
- package/package.json +67 -0
- package/types-B4Arep3V.d.cts +415 -0
- package/types-B4Arep3V.d.ts +415 -0
package/define.cjs
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/define.ts
|
|
21
|
+
var define_exports = {};
|
|
22
|
+
__export(define_exports, {
|
|
23
|
+
LoggerToken: () => LoggerToken,
|
|
24
|
+
SlotRegistry: () => SlotRegistry,
|
|
25
|
+
SlotRegistryToken: () => SlotRegistryToken,
|
|
26
|
+
defineRepository: () => defineRepository,
|
|
27
|
+
defineService: () => defineService,
|
|
28
|
+
defineSlot: () => defineSlot,
|
|
29
|
+
defineViewModel: () => defineViewModel,
|
|
30
|
+
logger: () => logger,
|
|
31
|
+
scopeLogger: () => scopeLogger
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(define_exports);
|
|
34
|
+
|
|
35
|
+
// src/define-service.ts
|
|
36
|
+
var import_ioc3 = require("@foxford/ioc");
|
|
37
|
+
|
|
38
|
+
// src/core/types.ts
|
|
39
|
+
var import_ioc = require("@foxford/ioc");
|
|
40
|
+
var ContainerManagerToken = (0, import_ioc.createToken)("core:ContainerManager");
|
|
41
|
+
var GuardRunnerToken = (0, import_ioc.createToken)("core:GuardRunner");
|
|
42
|
+
var NavigationManagerToken = (0, import_ioc.createToken)("core:NavigationManager");
|
|
43
|
+
var StateSerializerToken = (0, import_ioc.createToken)("core:StateSerializer");
|
|
44
|
+
var StateRegistryToken = (0, import_ioc.createToken)("core:StateRegistry");
|
|
45
|
+
var SlotRegistryToken = (0, import_ioc.createToken)("core:SlotRegistry");
|
|
46
|
+
var ActivatableToken = (0, import_ioc.createToken)("core:Activatable");
|
|
47
|
+
var RequestContextToken = (0, import_ioc.createToken)("core:RequestContext");
|
|
48
|
+
|
|
49
|
+
// src/logger.ts
|
|
50
|
+
var import_ioc2 = require("@foxford/ioc");
|
|
51
|
+
var import_logger = require("@foxford/logger");
|
|
52
|
+
var logger = import_logger.log.getLogger("@foxford/den");
|
|
53
|
+
var LoggerToken = (0, import_ioc2.createToken)("den:Logger");
|
|
54
|
+
function scopeLogger(container) {
|
|
55
|
+
if (container.has(LoggerToken)) {
|
|
56
|
+
const resolved = container.resolve(LoggerToken);
|
|
57
|
+
if (!(resolved instanceof Promise)) {
|
|
58
|
+
return resolved;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return logger;
|
|
62
|
+
}
|
|
63
|
+
function unitLogger(container, name) {
|
|
64
|
+
var _a;
|
|
65
|
+
const base = scopeLogger(container);
|
|
66
|
+
return (_a = base.getLogger(name)) != null ? _a : base;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/define-service.ts
|
|
70
|
+
function defineService(token, options) {
|
|
71
|
+
const { requires, create, activate, deactivate, serialize, deserialize, scope } = options;
|
|
72
|
+
const requireTokens = requires != null ? requires : [];
|
|
73
|
+
const participatesInState = serialize !== void 0 || deserialize !== void 0;
|
|
74
|
+
return {
|
|
75
|
+
__meta: { requires: requireTokens, scope: scope != null ? scope : "app" },
|
|
76
|
+
__type: "service",
|
|
77
|
+
/**
|
|
78
|
+
* Регистрирует сервис в IoC-контейнере как Singleton.
|
|
79
|
+
* Если передана create — биндит экземпляр класса напрямую.
|
|
80
|
+
* Иначе — биндит Activatable-обёртку с хуками lifecycle.
|
|
81
|
+
* Если объявлены serialize/deserialize — при создании экземпляра сервис
|
|
82
|
+
* регистрируется участником в StateRegistry этого контейнера.
|
|
83
|
+
* @param container - Контейнер для регистрации
|
|
84
|
+
*/
|
|
85
|
+
register(container) {
|
|
86
|
+
const unitLog = unitLogger(container, token.description);
|
|
87
|
+
const factory = (0, import_ioc3.inject)(requireTokens, (...args) => {
|
|
88
|
+
unitLog.debug(`\u0441\u043E\u0437\u0434\u0430\u043D\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (${create ? "\u0444\u0430\u0431\u0440\u0438\u043A\u0430" : "lifecycle-\u043E\u0431\u0451\u0440\u0442\u043A\u0430"})`);
|
|
89
|
+
let instance;
|
|
90
|
+
if (create) {
|
|
91
|
+
instance = create(args);
|
|
92
|
+
} else {
|
|
93
|
+
const service = {
|
|
94
|
+
activate(params) {
|
|
95
|
+
return activate == null ? void 0 : activate(args, params);
|
|
96
|
+
},
|
|
97
|
+
deactivate() {
|
|
98
|
+
return deactivate == null ? void 0 : deactivate(args);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
instance = service;
|
|
102
|
+
}
|
|
103
|
+
if (participatesInState) {
|
|
104
|
+
unitLog.debug("\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F \u0443\u0447\u0430\u0441\u0442\u043D\u0438\u043A\u043E\u043C StateRegistry (serialize/deserialize)");
|
|
105
|
+
registerStateParticipant(container, token, instance, args, serialize, deserialize);
|
|
106
|
+
}
|
|
107
|
+
return instance;
|
|
108
|
+
});
|
|
109
|
+
container.bind(token).toFactory(factory, { lifecycle: import_ioc3.Lifecycle.Singleton });
|
|
110
|
+
unitLog.debug(`\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (scope=${scope != null ? scope : "app"}, requires=${requireTokens.length})`);
|
|
111
|
+
},
|
|
112
|
+
token
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function registerStateParticipant(container, token, instance, deps, serialize, deserialize) {
|
|
116
|
+
if (!container.has(StateRegistryToken)) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const resolved = container.resolve(StateRegistryToken);
|
|
120
|
+
if (resolved instanceof Promise) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
;
|
|
124
|
+
resolved.add(token.description, {
|
|
125
|
+
activate: (params) => {
|
|
126
|
+
var _a;
|
|
127
|
+
return (_a = instance.activate) == null ? void 0 : _a.call(instance, params);
|
|
128
|
+
},
|
|
129
|
+
fromJSON: deserialize ? (data) => deserialize(deps, data) : void 0,
|
|
130
|
+
toJSON: serialize ? () => serialize(deps) : void 0
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// src/define-repository.ts
|
|
135
|
+
var import_ioc4 = require("@foxford/ioc");
|
|
136
|
+
function defineRepository(token, options) {
|
|
137
|
+
const { requires, create, scope } = options;
|
|
138
|
+
const requireTokens = requires != null ? requires : [];
|
|
139
|
+
return {
|
|
140
|
+
__meta: { requires: requireTokens, scope: scope != null ? scope : "app" },
|
|
141
|
+
__type: "repository",
|
|
142
|
+
/**
|
|
143
|
+
* Регистрирует репозиторий в IoC-контейнере как Singleton.
|
|
144
|
+
* Зависимости из requires резолвятся автоматически через inject.
|
|
145
|
+
* @param container - Контейнер для регистрации
|
|
146
|
+
*/
|
|
147
|
+
register(container) {
|
|
148
|
+
const unitLog = unitLogger(container, token.description);
|
|
149
|
+
const factory = (0, import_ioc4.inject)(requireTokens, (...args) => {
|
|
150
|
+
unitLog.debug("\u0441\u043E\u0437\u0434\u0430\u043D\u0438\u0435 \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F");
|
|
151
|
+
return create(args);
|
|
152
|
+
});
|
|
153
|
+
container.bind(token).toFactory(factory, { lifecycle: import_ioc4.Lifecycle.Singleton });
|
|
154
|
+
unitLog.debug(`\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F (scope=${scope != null ? scope : "app"}, requires=${requireTokens.length})`);
|
|
155
|
+
},
|
|
156
|
+
token
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// src/define-view-model.ts
|
|
161
|
+
var import_ioc5 = require("@foxford/ioc");
|
|
162
|
+
|
|
163
|
+
// src/adapter.ts
|
|
164
|
+
var activeResolver = null;
|
|
165
|
+
function resolveDefinition(token) {
|
|
166
|
+
if (activeResolver === null) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
`den/adapter: \u0440\u0435\u0437\u043E\u043B\u0432\u0435\u0440 \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D \u0434\u043B\u044F \xAB${token.description}\xBB \u2014 \u043D\u0438 \u043E\u0434\u0438\u043D host-\u0430\u0434\u0430\u043F\u0442\u0435\u0440 \u043D\u0435 \u0432\u044B\u0437\u0432\u0430\u043B installResolver()`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
return activeResolver(token);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// src/define-view-model.ts
|
|
175
|
+
function defineViewModel(token, options) {
|
|
176
|
+
const { requires, create } = options;
|
|
177
|
+
const requireTokens = requires != null ? requires : [];
|
|
178
|
+
return {
|
|
179
|
+
__meta: { requires: requireTokens },
|
|
180
|
+
__type: "view-model",
|
|
181
|
+
/**
|
|
182
|
+
* Регистрирует VM в IoC-контейнере как Singleton.
|
|
183
|
+
* Зависимости из requires резолвятся автоматически через inject.
|
|
184
|
+
* @param container - Контейнер для регистрации
|
|
185
|
+
*/
|
|
186
|
+
register(container) {
|
|
187
|
+
const unitLog = unitLogger(container, token.description);
|
|
188
|
+
const factory = (0, import_ioc5.inject)(requireTokens, (...args) => {
|
|
189
|
+
unitLog.debug("\u0441\u043E\u0437\u0434\u0430\u043D\u0438\u0435 view-model");
|
|
190
|
+
return create(args);
|
|
191
|
+
});
|
|
192
|
+
container.bind(token).toFactory(factory, { lifecycle: import_ioc5.Lifecycle.Singleton });
|
|
193
|
+
unitLog.debug(`\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F view-model (requires=${requireTokens.length})`);
|
|
194
|
+
},
|
|
195
|
+
/**
|
|
196
|
+
* Резолвит VM через стратегию активного host-адаптера.
|
|
197
|
+
* Вызывайте когда контейнер уже инициализирован (в render-контексте).
|
|
198
|
+
*
|
|
199
|
+
* Дескриптор не знает, откуда берётся инстанс — стратегию ставит адаптер
|
|
200
|
+
* через `installResolver()` (см. `@foxford/den/adapter`):
|
|
201
|
+
* - Vike (дефолт) — async/global: подъём по parent-chain, pending Promise при промахе;
|
|
202
|
+
* - Next — sync/island: контейнер острова из React-контекста.
|
|
203
|
+
*
|
|
204
|
+
* @returns Экземпляр VM или Promise с экземпляром
|
|
205
|
+
*/
|
|
206
|
+
resolve() {
|
|
207
|
+
return resolveDefinition(token);
|
|
208
|
+
},
|
|
209
|
+
token,
|
|
210
|
+
/**
|
|
211
|
+
* Псевдоним для resolve(). Резолвит VM через стратегию активного адаптера.
|
|
212
|
+
* @returns Экземпляр VM или Promise с экземпляром
|
|
213
|
+
*/
|
|
214
|
+
use() {
|
|
215
|
+
return this.resolve();
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// src/core/slot-registry.ts
|
|
221
|
+
var SlotRegistry = class {
|
|
222
|
+
constructor() {
|
|
223
|
+
/** Слоты по имени. Повторная регистрация с тем же именем перезаписывает. */
|
|
224
|
+
this.slots = /* @__PURE__ */ new Map();
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Регистрирует слот.
|
|
228
|
+
* @param entry - Запись слота (имя + непрозрачный view)
|
|
229
|
+
*/
|
|
230
|
+
add(entry) {
|
|
231
|
+
this.slots.set(entry.name, entry);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Возвращает слот по имени.
|
|
235
|
+
* @param name - Имя слота
|
|
236
|
+
*/
|
|
237
|
+
get(name) {
|
|
238
|
+
return this.slots.get(name);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Возвращает все зарегистрированные слоты.
|
|
242
|
+
*/
|
|
243
|
+
all() {
|
|
244
|
+
return [...this.slots.values()];
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// src/define-slot.ts
|
|
249
|
+
function defineSlot({ name, view, units = [] }) {
|
|
250
|
+
return {
|
|
251
|
+
__type: "slot",
|
|
252
|
+
name,
|
|
253
|
+
register(container) {
|
|
254
|
+
const slotLog = unitLogger(container, `slot:${name}`);
|
|
255
|
+
for (const unit of units) {
|
|
256
|
+
unit.register(container);
|
|
257
|
+
}
|
|
258
|
+
const registry = container.has(SlotRegistryToken) ? container.resolve(SlotRegistryToken) : (() => {
|
|
259
|
+
const created = new SlotRegistry();
|
|
260
|
+
container.bind(SlotRegistryToken).toValue(created);
|
|
261
|
+
slotLog.debug("\u0441\u043E\u0437\u0434\u0430\u043D SlotRegistry \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440\u0430");
|
|
262
|
+
return created;
|
|
263
|
+
})();
|
|
264
|
+
registry.add({ name, view });
|
|
265
|
+
slotLog.debug(`\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F \u0441\u043B\u043E\u0442\u0430 (units=${units.length})`);
|
|
266
|
+
},
|
|
267
|
+
units,
|
|
268
|
+
view
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
272
|
+
0 && (module.exports = {
|
|
273
|
+
LoggerToken,
|
|
274
|
+
SlotRegistry,
|
|
275
|
+
SlotRegistryToken,
|
|
276
|
+
defineRepository,
|
|
277
|
+
defineService,
|
|
278
|
+
defineSlot,
|
|
279
|
+
defineViewModel,
|
|
280
|
+
logger,
|
|
281
|
+
scopeLogger
|
|
282
|
+
});
|
package/define.d.cts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export { m as DefineRepositoryOptions, n as DefineServiceOptions, o as DefineSlotOptions, p as DefineViewModelOptions, q as Definition, R as RepositoryDefinition, S as ServiceDefinition, r as SlotDefinition, V as ViewModelDefinition, s as defineRepository, t as defineService, u as defineSlot, v as defineViewModel } from './define-slot-es1K6_-L.cjs';
|
|
2
|
+
export { k as SlotEntry, l as SlotRegistry, m as SlotRegistryToken } from './types-B4Arep3V.cjs';
|
|
3
|
+
import { Token, Container } from '@foxford/ioc';
|
|
4
|
+
import { HierarchicalLogger } from '@foxford/logger';
|
|
5
|
+
|
|
6
|
+
/** Корневой логгер ядра — фолбэк, когда в контейнере нет scope-логгера (тесты, Vike). */
|
|
7
|
+
declare const logger: HierarchicalLogger;
|
|
8
|
+
/**
|
|
9
|
+
* Токен per-scope логгера приложения. Драйвер биндит сюда логгер текущего скоупа
|
|
10
|
+
* (`toValue`), `define*` его резолвят через {@link scopeLogger}. Живёт в ядре, а не в
|
|
11
|
+
* приложении, потому что это framework-контракт — им пользуются все адаптеры и оркестраторы.
|
|
12
|
+
*/
|
|
13
|
+
declare const LoggerToken: Token<HierarchicalLogger>;
|
|
14
|
+
/**
|
|
15
|
+
* Достаёт scope-логгер из контейнера (get-or-fallback).
|
|
16
|
+
*
|
|
17
|
+
* Возвращает логгер приложения, если драйвер забиндил его под {@link LoggerToken};
|
|
18
|
+
* иначе — корневой {@link logger} ядра. Резолв синхронный (`toValue`), но на всякий
|
|
19
|
+
* случай отсекаем Promise, чтобы контракт остался «всегда HierarchicalLogger».
|
|
20
|
+
*
|
|
21
|
+
* @param container - Скоуп-контейнер (острова/запроса/страницы)
|
|
22
|
+
* @returns Логгер приложения либо корневой логгер ядра
|
|
23
|
+
*/
|
|
24
|
+
declare function scopeLogger(container: Container): HierarchicalLogger;
|
|
25
|
+
|
|
26
|
+
export { LoggerToken, logger, scopeLogger };
|
package/define.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export { m as DefineRepositoryOptions, n as DefineServiceOptions, o as DefineSlotOptions, p as DefineViewModelOptions, q as Definition, R as RepositoryDefinition, S as ServiceDefinition, r as SlotDefinition, V as ViewModelDefinition, s as defineRepository, t as defineService, u as defineSlot, v as defineViewModel } from './define-slot--HM6B232.js';
|
|
2
|
+
export { k as SlotEntry, l as SlotRegistry, m as SlotRegistryToken } from './types-B4Arep3V.js';
|
|
3
|
+
import { Token, Container } from '@foxford/ioc';
|
|
4
|
+
import { HierarchicalLogger } from '@foxford/logger';
|
|
5
|
+
|
|
6
|
+
/** Корневой логгер ядра — фолбэк, когда в контейнере нет scope-логгера (тесты, Vike). */
|
|
7
|
+
declare const logger: HierarchicalLogger;
|
|
8
|
+
/**
|
|
9
|
+
* Токен per-scope логгера приложения. Драйвер биндит сюда логгер текущего скоупа
|
|
10
|
+
* (`toValue`), `define*` его резолвят через {@link scopeLogger}. Живёт в ядре, а не в
|
|
11
|
+
* приложении, потому что это framework-контракт — им пользуются все адаптеры и оркестраторы.
|
|
12
|
+
*/
|
|
13
|
+
declare const LoggerToken: Token<HierarchicalLogger>;
|
|
14
|
+
/**
|
|
15
|
+
* Достаёт scope-логгер из контейнера (get-or-fallback).
|
|
16
|
+
*
|
|
17
|
+
* Возвращает логгер приложения, если драйвер забиндил его под {@link LoggerToken};
|
|
18
|
+
* иначе — корневой {@link logger} ядра. Резолв синхронный (`toValue`), но на всякий
|
|
19
|
+
* случай отсекаем Promise, чтобы контракт остался «всегда HierarchicalLogger».
|
|
20
|
+
*
|
|
21
|
+
* @param container - Скоуп-контейнер (острова/запроса/страницы)
|
|
22
|
+
* @returns Логгер приложения либо корневой логгер ядра
|
|
23
|
+
*/
|
|
24
|
+
declare function scopeLogger(container: Container): HierarchicalLogger;
|
|
25
|
+
|
|
26
|
+
export { LoggerToken, logger, scopeLogger };
|
package/define.mjs
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
// src/define-service.ts
|
|
2
|
+
import { inject, Lifecycle } from "@foxford/ioc";
|
|
3
|
+
|
|
4
|
+
// src/core/types.ts
|
|
5
|
+
import { createToken } from "@foxford/ioc";
|
|
6
|
+
var ContainerManagerToken = createToken("core:ContainerManager");
|
|
7
|
+
var GuardRunnerToken = createToken("core:GuardRunner");
|
|
8
|
+
var NavigationManagerToken = createToken("core:NavigationManager");
|
|
9
|
+
var StateSerializerToken = createToken("core:StateSerializer");
|
|
10
|
+
var StateRegistryToken = createToken("core:StateRegistry");
|
|
11
|
+
var SlotRegistryToken = createToken("core:SlotRegistry");
|
|
12
|
+
var ActivatableToken = createToken("core:Activatable");
|
|
13
|
+
var RequestContextToken = createToken("core:RequestContext");
|
|
14
|
+
|
|
15
|
+
// src/logger.ts
|
|
16
|
+
import { createToken as createToken2 } from "@foxford/ioc";
|
|
17
|
+
import { log } from "@foxford/logger";
|
|
18
|
+
var logger = log.getLogger("@foxford/den");
|
|
19
|
+
var LoggerToken = createToken2("den:Logger");
|
|
20
|
+
function scopeLogger(container) {
|
|
21
|
+
if (container.has(LoggerToken)) {
|
|
22
|
+
const resolved = container.resolve(LoggerToken);
|
|
23
|
+
if (!(resolved instanceof Promise)) {
|
|
24
|
+
return resolved;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return logger;
|
|
28
|
+
}
|
|
29
|
+
function unitLogger(container, name) {
|
|
30
|
+
var _a;
|
|
31
|
+
const base = scopeLogger(container);
|
|
32
|
+
return (_a = base.getLogger(name)) != null ? _a : base;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/define-service.ts
|
|
36
|
+
function defineService(token, options) {
|
|
37
|
+
const { requires, create, activate, deactivate, serialize, deserialize, scope } = options;
|
|
38
|
+
const requireTokens = requires != null ? requires : [];
|
|
39
|
+
const participatesInState = serialize !== void 0 || deserialize !== void 0;
|
|
40
|
+
return {
|
|
41
|
+
__meta: { requires: requireTokens, scope: scope != null ? scope : "app" },
|
|
42
|
+
__type: "service",
|
|
43
|
+
/**
|
|
44
|
+
* Регистрирует сервис в IoC-контейнере как Singleton.
|
|
45
|
+
* Если передана create — биндит экземпляр класса напрямую.
|
|
46
|
+
* Иначе — биндит Activatable-обёртку с хуками lifecycle.
|
|
47
|
+
* Если объявлены serialize/deserialize — при создании экземпляра сервис
|
|
48
|
+
* регистрируется участником в StateRegistry этого контейнера.
|
|
49
|
+
* @param container - Контейнер для регистрации
|
|
50
|
+
*/
|
|
51
|
+
register(container) {
|
|
52
|
+
const unitLog = unitLogger(container, token.description);
|
|
53
|
+
const factory = inject(requireTokens, (...args) => {
|
|
54
|
+
unitLog.debug(`\u0441\u043E\u0437\u0434\u0430\u043D\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (${create ? "\u0444\u0430\u0431\u0440\u0438\u043A\u0430" : "lifecycle-\u043E\u0431\u0451\u0440\u0442\u043A\u0430"})`);
|
|
55
|
+
let instance;
|
|
56
|
+
if (create) {
|
|
57
|
+
instance = create(args);
|
|
58
|
+
} else {
|
|
59
|
+
const service = {
|
|
60
|
+
activate(params) {
|
|
61
|
+
return activate == null ? void 0 : activate(args, params);
|
|
62
|
+
},
|
|
63
|
+
deactivate() {
|
|
64
|
+
return deactivate == null ? void 0 : deactivate(args);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
instance = service;
|
|
68
|
+
}
|
|
69
|
+
if (participatesInState) {
|
|
70
|
+
unitLog.debug("\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F \u0443\u0447\u0430\u0441\u0442\u043D\u0438\u043A\u043E\u043C StateRegistry (serialize/deserialize)");
|
|
71
|
+
registerStateParticipant(container, token, instance, args, serialize, deserialize);
|
|
72
|
+
}
|
|
73
|
+
return instance;
|
|
74
|
+
});
|
|
75
|
+
container.bind(token).toFactory(factory, { lifecycle: Lifecycle.Singleton });
|
|
76
|
+
unitLog.debug(`\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (scope=${scope != null ? scope : "app"}, requires=${requireTokens.length})`);
|
|
77
|
+
},
|
|
78
|
+
token
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function registerStateParticipant(container, token, instance, deps, serialize, deserialize) {
|
|
82
|
+
if (!container.has(StateRegistryToken)) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const resolved = container.resolve(StateRegistryToken);
|
|
86
|
+
if (resolved instanceof Promise) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
;
|
|
90
|
+
resolved.add(token.description, {
|
|
91
|
+
activate: (params) => {
|
|
92
|
+
var _a;
|
|
93
|
+
return (_a = instance.activate) == null ? void 0 : _a.call(instance, params);
|
|
94
|
+
},
|
|
95
|
+
fromJSON: deserialize ? (data) => deserialize(deps, data) : void 0,
|
|
96
|
+
toJSON: serialize ? () => serialize(deps) : void 0
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// src/define-repository.ts
|
|
101
|
+
import { inject as inject2, Lifecycle as Lifecycle2 } from "@foxford/ioc";
|
|
102
|
+
function defineRepository(token, options) {
|
|
103
|
+
const { requires, create, scope } = options;
|
|
104
|
+
const requireTokens = requires != null ? requires : [];
|
|
105
|
+
return {
|
|
106
|
+
__meta: { requires: requireTokens, scope: scope != null ? scope : "app" },
|
|
107
|
+
__type: "repository",
|
|
108
|
+
/**
|
|
109
|
+
* Регистрирует репозиторий в IoC-контейнере как Singleton.
|
|
110
|
+
* Зависимости из requires резолвятся автоматически через inject.
|
|
111
|
+
* @param container - Контейнер для регистрации
|
|
112
|
+
*/
|
|
113
|
+
register(container) {
|
|
114
|
+
const unitLog = unitLogger(container, token.description);
|
|
115
|
+
const factory = inject2(requireTokens, (...args) => {
|
|
116
|
+
unitLog.debug("\u0441\u043E\u0437\u0434\u0430\u043D\u0438\u0435 \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F");
|
|
117
|
+
return create(args);
|
|
118
|
+
});
|
|
119
|
+
container.bind(token).toFactory(factory, { lifecycle: Lifecycle2.Singleton });
|
|
120
|
+
unitLog.debug(`\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F (scope=${scope != null ? scope : "app"}, requires=${requireTokens.length})`);
|
|
121
|
+
},
|
|
122
|
+
token
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// src/define-view-model.ts
|
|
127
|
+
import { inject as inject3, Lifecycle as Lifecycle3 } from "@foxford/ioc";
|
|
128
|
+
|
|
129
|
+
// src/adapter.ts
|
|
130
|
+
var activeResolver = null;
|
|
131
|
+
function resolveDefinition(token) {
|
|
132
|
+
if (activeResolver === null) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`den/adapter: \u0440\u0435\u0437\u043E\u043B\u0432\u0435\u0440 \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D \u0434\u043B\u044F \xAB${token.description}\xBB \u2014 \u043D\u0438 \u043E\u0434\u0438\u043D host-\u0430\u0434\u0430\u043F\u0442\u0435\u0440 \u043D\u0435 \u0432\u044B\u0437\u0432\u0430\u043B installResolver()`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
return activeResolver(token);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// src/define-view-model.ts
|
|
141
|
+
function defineViewModel(token, options) {
|
|
142
|
+
const { requires, create } = options;
|
|
143
|
+
const requireTokens = requires != null ? requires : [];
|
|
144
|
+
return {
|
|
145
|
+
__meta: { requires: requireTokens },
|
|
146
|
+
__type: "view-model",
|
|
147
|
+
/**
|
|
148
|
+
* Регистрирует VM в IoC-контейнере как Singleton.
|
|
149
|
+
* Зависимости из requires резолвятся автоматически через inject.
|
|
150
|
+
* @param container - Контейнер для регистрации
|
|
151
|
+
*/
|
|
152
|
+
register(container) {
|
|
153
|
+
const unitLog = unitLogger(container, token.description);
|
|
154
|
+
const factory = inject3(requireTokens, (...args) => {
|
|
155
|
+
unitLog.debug("\u0441\u043E\u0437\u0434\u0430\u043D\u0438\u0435 view-model");
|
|
156
|
+
return create(args);
|
|
157
|
+
});
|
|
158
|
+
container.bind(token).toFactory(factory, { lifecycle: Lifecycle3.Singleton });
|
|
159
|
+
unitLog.debug(`\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F view-model (requires=${requireTokens.length})`);
|
|
160
|
+
},
|
|
161
|
+
/**
|
|
162
|
+
* Резолвит VM через стратегию активного host-адаптера.
|
|
163
|
+
* Вызывайте когда контейнер уже инициализирован (в render-контексте).
|
|
164
|
+
*
|
|
165
|
+
* Дескриптор не знает, откуда берётся инстанс — стратегию ставит адаптер
|
|
166
|
+
* через `installResolver()` (см. `@foxford/den/adapter`):
|
|
167
|
+
* - Vike (дефолт) — async/global: подъём по parent-chain, pending Promise при промахе;
|
|
168
|
+
* - Next — sync/island: контейнер острова из React-контекста.
|
|
169
|
+
*
|
|
170
|
+
* @returns Экземпляр VM или Promise с экземпляром
|
|
171
|
+
*/
|
|
172
|
+
resolve() {
|
|
173
|
+
return resolveDefinition(token);
|
|
174
|
+
},
|
|
175
|
+
token,
|
|
176
|
+
/**
|
|
177
|
+
* Псевдоним для resolve(). Резолвит VM через стратегию активного адаптера.
|
|
178
|
+
* @returns Экземпляр VM или Promise с экземпляром
|
|
179
|
+
*/
|
|
180
|
+
use() {
|
|
181
|
+
return this.resolve();
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// src/core/slot-registry.ts
|
|
187
|
+
var SlotRegistry = class {
|
|
188
|
+
constructor() {
|
|
189
|
+
/** Слоты по имени. Повторная регистрация с тем же именем перезаписывает. */
|
|
190
|
+
this.slots = /* @__PURE__ */ new Map();
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Регистрирует слот.
|
|
194
|
+
* @param entry - Запись слота (имя + непрозрачный view)
|
|
195
|
+
*/
|
|
196
|
+
add(entry) {
|
|
197
|
+
this.slots.set(entry.name, entry);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Возвращает слот по имени.
|
|
201
|
+
* @param name - Имя слота
|
|
202
|
+
*/
|
|
203
|
+
get(name) {
|
|
204
|
+
return this.slots.get(name);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Возвращает все зарегистрированные слоты.
|
|
208
|
+
*/
|
|
209
|
+
all() {
|
|
210
|
+
return [...this.slots.values()];
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// src/define-slot.ts
|
|
215
|
+
function defineSlot({ name, view, units = [] }) {
|
|
216
|
+
return {
|
|
217
|
+
__type: "slot",
|
|
218
|
+
name,
|
|
219
|
+
register(container) {
|
|
220
|
+
const slotLog = unitLogger(container, `slot:${name}`);
|
|
221
|
+
for (const unit of units) {
|
|
222
|
+
unit.register(container);
|
|
223
|
+
}
|
|
224
|
+
const registry = container.has(SlotRegistryToken) ? container.resolve(SlotRegistryToken) : (() => {
|
|
225
|
+
const created = new SlotRegistry();
|
|
226
|
+
container.bind(SlotRegistryToken).toValue(created);
|
|
227
|
+
slotLog.debug("\u0441\u043E\u0437\u0434\u0430\u043D SlotRegistry \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440\u0430");
|
|
228
|
+
return created;
|
|
229
|
+
})();
|
|
230
|
+
registry.add({ name, view });
|
|
231
|
+
slotLog.debug(`\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F \u0441\u043B\u043E\u0442\u0430 (units=${units.length})`);
|
|
232
|
+
},
|
|
233
|
+
units,
|
|
234
|
+
view
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
export {
|
|
238
|
+
LoggerToken,
|
|
239
|
+
SlotRegistry,
|
|
240
|
+
SlotRegistryToken,
|
|
241
|
+
defineRepository,
|
|
242
|
+
defineService,
|
|
243
|
+
defineSlot,
|
|
244
|
+
defineViewModel,
|
|
245
|
+
logger,
|
|
246
|
+
scopeLogger
|
|
247
|
+
};
|