@foxford/den 3.3.0 → 3.5.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 +17 -5
- package/adapter.d.cts +1 -1
- package/adapter.d.ts +1 -1
- package/{chunk-XDM6J4LJ.cjs → chunk-JMRHLOBD.cjs} +63 -7
- package/{chunk-SOH2TL2N.js → chunk-VO3ORM7Z.js} +62 -6
- package/{define-repository-q_T4hqeP.d.ts → define-repository-AO7JI6Cb.d.ts} +1 -1
- package/{define-repository-CwAXed2X.d.cts → define-repository-C0MI-J32.d.cts} +1 -1
- package/{define-slot-DouHW8RK.d.cts → define-slot-BEeHNEph.d.cts} +1 -1
- package/{define-slot-TkqbLySB.d.ts → define-slot-CdWdFM16.d.ts} +1 -1
- package/define.d.cts +3 -3
- package/define.d.ts +3 -3
- package/{descriptor-tWPa9j-x.d.ts → descriptor-BSaHM5B4.d.ts} +14 -2
- package/{descriptor-w8oxeIAe.d.cts → descriptor-C2j6Zz6c.d.cts} +14 -2
- package/index.d.cts +6 -6
- package/index.d.ts +6 -6
- package/island/index.cjs +16 -3
- package/island/index.d.cts +62 -6
- package/island/index.d.ts +62 -6
- package/island/index.js +15 -2
- package/package.json +17 -17
- package/{routes-B0hDrkiF.d.cts → routes-BvV405k4.d.cts} +1 -1
- package/{routes-0uXJ0fux.d.ts → routes-Di3K_0uQ.d.ts} +1 -1
- package/serve/index.cjs +48 -41
- package/serve/index.d.cts +4 -4
- package/serve/index.d.ts +4 -4
- package/serve/index.js +46 -39
- package/{types-Dx5qGiwk.d.cts → types-BxMQ-VOd.d.cts} +1 -1
- package/{types-Dx5qGiwk.d.ts → types-BxMQ-VOd.d.ts} +1 -1
- package/{view-adapter-DF1me25J.d.cts → view-adapter-DMLlp3Iu.d.cts} +2 -2
- package/{view-adapter-BV62bdhM.d.ts → view-adapter-DNLRSFka.d.ts} +2 -2
package/README.mdx
CHANGED
|
@@ -84,9 +84,16 @@ const { status, html, state, head, headHtml, redirect, assets } = await renderAp
|
|
|
84
84
|
pathname: '/legal/general',
|
|
85
85
|
search: '?from=footer',
|
|
86
86
|
context: { cookies, headers }, // реквизиты браузерного запроса
|
|
87
|
+
inputs: { 'host:User': user, 'host:Settings': settings }, // входные данные хоста по ключу token.description
|
|
87
88
|
})
|
|
88
89
|
```
|
|
89
90
|
|
|
91
|
+
`inputs` — то, что хост знает про запрос и отдаёт приложению данными: посетитель, настройки
|
|
92
|
+
площадки, эксперименты (токены — в `@foxford/contracts`). Приложение объявляет, что принимает,
|
|
93
|
+
полем `inputs` дескриптора и читает через `requires`; ядро биндит объявленное в контейнер
|
|
94
|
+
острова, кладёт в `state` рядом с VM и в браузере биндит оттуда же — единица не различает
|
|
95
|
+
сторон. Не объявленное в контейнер не попадает, не присланное не биндится.
|
|
96
|
+
|
|
90
97
|
`status` — исход запроса: `200` значит «вот страница», всё остальное значит, что страницы по
|
|
91
98
|
этому адресу нет, и тело такого ответа выбирает хост. `state` едет в документ и гидрирует
|
|
92
99
|
остров в браузере, `headHtml` — стили, собранные во время рендера. `assets` — ссылки на
|
|
@@ -177,11 +184,16 @@ describeDocument(): DocumentContribution {
|
|
|
177
184
|
|
|
178
185
|
Рантайм вокруг дескриптора отдаёт три ручки:
|
|
179
186
|
|
|
180
|
-
| Ручка
|
|
181
|
-
|
|
|
182
|
-
| `
|
|
183
|
-
| `GET /
|
|
184
|
-
| `GET /
|
|
187
|
+
| Ручка | Ответ |
|
|
188
|
+
| -------------------------------------- | ------------------------------------------- |
|
|
189
|
+
| `QUERY /_render` + `{ url, inputs? }` | `200` + ответ `renderApp` телом |
|
|
190
|
+
| `GET /_render?url=<path+search>` | то же без входных данных хоста |
|
|
191
|
+
| `GET /_routes` | `200` + массив regex-строк заявки на адреса |
|
|
192
|
+
| `GET /_health` | `200 ok` |
|
|
193
|
+
|
|
194
|
+
`QUERY` — безопасный метод с телом (RFC 9110): адрес и входные данные хоста едут JSON-ом,
|
|
195
|
+
потому что заголовкам они не по размеру. `GET` остаётся для хоста, который входных данных
|
|
196
|
+
не шлёт.
|
|
185
197
|
|
|
186
198
|
**Статус HTTP описывает транспорт, а исход страницы едет полем `status` в теле.** `200` значит
|
|
187
199
|
«приложение ответило» — хоть `404`, хоть редиректом. Всё остальное значит «до приложения не
|
package/adapter.d.cts
CHANGED
package/adapter.d.ts
CHANGED
|
@@ -19,6 +19,57 @@ function isDocumentSource(value) {
|
|
|
19
19
|
return typeof value === "object" && value !== null && typeof value.describeDocument === "function";
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
// src/island/inputs.ts
|
|
23
|
+
function islandInputsOf(descriptor, source) {
|
|
24
|
+
var _a;
|
|
25
|
+
const inputs = {};
|
|
26
|
+
if (source === void 0) {
|
|
27
|
+
return inputs;
|
|
28
|
+
}
|
|
29
|
+
for (const token of (_a = descriptor.requires) != null ? _a : []) {
|
|
30
|
+
const value = source[token.description];
|
|
31
|
+
if (value !== void 0) {
|
|
32
|
+
inputs[token.description] = value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return inputs;
|
|
36
|
+
}
|
|
37
|
+
function bindIslandInputs(container, descriptor, inputs) {
|
|
38
|
+
var _a;
|
|
39
|
+
if (inputs === void 0) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
for (const token of (_a = descriptor.requires) != null ? _a : []) {
|
|
43
|
+
const value = inputs[token.description];
|
|
44
|
+
if (value !== void 0) {
|
|
45
|
+
container.bind(token).toValue(value);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function parseCookieHeader(header) {
|
|
50
|
+
const cookies = {};
|
|
51
|
+
for (const part of (header != null ? header : "").split(";")) {
|
|
52
|
+
const eq = part.indexOf("=");
|
|
53
|
+
if (eq < 1) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const name = part.slice(0, eq).trim();
|
|
57
|
+
if (name && !(name in cookies)) {
|
|
58
|
+
cookies[name] = part.slice(eq + 1).trim();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return cookies;
|
|
62
|
+
}
|
|
63
|
+
function browserRequestContext() {
|
|
64
|
+
const cookie = typeof document === "undefined" ? void 0 : document.cookie;
|
|
65
|
+
return { cookies: parseCookieHeader(cookie), headers: {} };
|
|
66
|
+
}
|
|
67
|
+
function bindRequestContext(container, context) {
|
|
68
|
+
if (context !== void 0) {
|
|
69
|
+
container.bind(_chunk6QV4L6R2cjs.RequestContextToken).toValue(context);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
22
73
|
// src/island/runtime.ts
|
|
23
74
|
var _ioc = require('@foxford/ioc');
|
|
24
75
|
var appContainer = null;
|
|
@@ -55,12 +106,14 @@ function registerIslandParts(container, descriptor, islandLog) {
|
|
|
55
106
|
}
|
|
56
107
|
function createIslandContainer(descriptor, options = {}) {
|
|
57
108
|
var _a, _b, _c;
|
|
58
|
-
const { parent = getAppContainer() } = options;
|
|
109
|
+
const { context, inputs, parent = getAppContainer() } = options;
|
|
59
110
|
const appLog = (_b = _logger.log.getLogger((_a = descriptor.name) != null ? _a : "app")) != null ? _b : _chunkA6ZPAM6Zcjs.logger;
|
|
60
111
|
const islandLog = (_c = appLog.getLogger("client")) != null ? _c : appLog;
|
|
61
112
|
try {
|
|
62
113
|
const container = parent.createChild();
|
|
63
114
|
container.bind(_chunkA6ZPAM6Zcjs.LoggerToken).toValue(islandLog);
|
|
115
|
+
bindRequestContext(container, context);
|
|
116
|
+
bindIslandInputs(container, descriptor, inputs);
|
|
64
117
|
registerIslandParts(container, descriptor, islandLog);
|
|
65
118
|
return container;
|
|
66
119
|
} catch (error) {
|
|
@@ -166,14 +219,12 @@ function renderApp(descriptor, request) {
|
|
|
166
219
|
pathname: request.pathname,
|
|
167
220
|
search: (_b = request.search) != null ? _b : ""
|
|
168
221
|
};
|
|
169
|
-
const
|
|
222
|
+
const inputs = islandInputsOf(descriptor, request.inputs);
|
|
223
|
+
const container = createIslandContainer(descriptor, { context: request.context, inputs, parent: request.parent });
|
|
170
224
|
if (container === null) {
|
|
171
225
|
throw new Error(`den/island: \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \xAB${descriptor.name}\xBB \u043D\u0435 \u0441\u043E\u0431\u0440\u0430\u043B\u043E\u0441\u044C \u2014 \u0440\u0435\u043D\u0434\u0435\u0440 \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u0435\u043D`);
|
|
172
226
|
}
|
|
173
227
|
try {
|
|
174
|
-
if (request.context) {
|
|
175
|
-
container.bind(_chunk6QV4L6R2cjs.RequestContextToken).toValue(request.context);
|
|
176
|
-
}
|
|
177
228
|
yield activateIslandViewModels(container, descriptor, route);
|
|
178
229
|
const contribution = collectDocumentContribution(container, descriptor);
|
|
179
230
|
const { data, head, redirect, status = STATUS_OK } = contribution;
|
|
@@ -181,7 +232,7 @@ function renderApp(descriptor, request) {
|
|
|
181
232
|
return { data, head, html: "", redirect, state: {}, status };
|
|
182
233
|
}
|
|
183
234
|
const assets = (_c = contribution.assets) != null ? _c : descriptor.assets;
|
|
184
|
-
const state = collectIslandState(container, descriptor);
|
|
235
|
+
const state = _chunkT5QVCXVBcjs.__spreadValues.call(void 0, _chunkT5QVCXVBcjs.__spreadValues.call(void 0, {}, inputs), collectIslandState(container, descriptor));
|
|
185
236
|
if (descriptor.view === void 0 || descriptor.viewLayer === void 0) {
|
|
186
237
|
return { assets, data, head, html: "", state, status };
|
|
187
238
|
}
|
|
@@ -242,4 +293,9 @@ function pathPattern(pattern) {
|
|
|
242
293
|
|
|
243
294
|
|
|
244
295
|
|
|
245
|
-
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
exports.isDocumentSource = isDocumentSource; exports.islandInputsOf = islandInputsOf; exports.bindIslandInputs = bindIslandInputs; exports.parseCookieHeader = parseCookieHeader; exports.browserRequestContext = browserRequestContext; exports.bindRequestContext = bindRequestContext; exports.getAppContainer = getAppContainer; exports.createIslandContainer = createIslandContainer; exports.hydrateIslandState = hydrateIslandState; exports.activateIslandViewModels = activateIslandViewModels; exports.collectIslandState = collectIslandState; exports.collectDocumentContribution = collectDocumentContribution; exports.resolveEagerUnits = resolveEagerUnits; exports.renderApp = renderApp; exports.normalizeRoutes = normalizeRoutes; exports.matchRoute = matchRoute; exports.pathPattern = pathPattern;
|
|
@@ -19,6 +19,57 @@ function isDocumentSource(value) {
|
|
|
19
19
|
return typeof value === "object" && value !== null && typeof value.describeDocument === "function";
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
// src/island/inputs.ts
|
|
23
|
+
function islandInputsOf(descriptor, source) {
|
|
24
|
+
var _a;
|
|
25
|
+
const inputs = {};
|
|
26
|
+
if (source === void 0) {
|
|
27
|
+
return inputs;
|
|
28
|
+
}
|
|
29
|
+
for (const token of (_a = descriptor.requires) != null ? _a : []) {
|
|
30
|
+
const value = source[token.description];
|
|
31
|
+
if (value !== void 0) {
|
|
32
|
+
inputs[token.description] = value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return inputs;
|
|
36
|
+
}
|
|
37
|
+
function bindIslandInputs(container, descriptor, inputs) {
|
|
38
|
+
var _a;
|
|
39
|
+
if (inputs === void 0) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
for (const token of (_a = descriptor.requires) != null ? _a : []) {
|
|
43
|
+
const value = inputs[token.description];
|
|
44
|
+
if (value !== void 0) {
|
|
45
|
+
container.bind(token).toValue(value);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function parseCookieHeader(header) {
|
|
50
|
+
const cookies = {};
|
|
51
|
+
for (const part of (header != null ? header : "").split(";")) {
|
|
52
|
+
const eq = part.indexOf("=");
|
|
53
|
+
if (eq < 1) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const name = part.slice(0, eq).trim();
|
|
57
|
+
if (name && !(name in cookies)) {
|
|
58
|
+
cookies[name] = part.slice(eq + 1).trim();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return cookies;
|
|
62
|
+
}
|
|
63
|
+
function browserRequestContext() {
|
|
64
|
+
const cookie = typeof document === "undefined" ? void 0 : document.cookie;
|
|
65
|
+
return { cookies: parseCookieHeader(cookie), headers: {} };
|
|
66
|
+
}
|
|
67
|
+
function bindRequestContext(container, context) {
|
|
68
|
+
if (context !== void 0) {
|
|
69
|
+
container.bind(RequestContextToken).toValue(context);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
22
73
|
// src/island/runtime.ts
|
|
23
74
|
import { Container } from "@foxford/ioc";
|
|
24
75
|
var appContainer = null;
|
|
@@ -55,12 +106,14 @@ function registerIslandParts(container, descriptor, islandLog) {
|
|
|
55
106
|
}
|
|
56
107
|
function createIslandContainer(descriptor, options = {}) {
|
|
57
108
|
var _a, _b, _c;
|
|
58
|
-
const { parent = getAppContainer() } = options;
|
|
109
|
+
const { context, inputs, parent = getAppContainer() } = options;
|
|
59
110
|
const appLog = (_b = log.getLogger((_a = descriptor.name) != null ? _a : "app")) != null ? _b : logger;
|
|
60
111
|
const islandLog = (_c = appLog.getLogger("client")) != null ? _c : appLog;
|
|
61
112
|
try {
|
|
62
113
|
const container = parent.createChild();
|
|
63
114
|
container.bind(LoggerToken).toValue(islandLog);
|
|
115
|
+
bindRequestContext(container, context);
|
|
116
|
+
bindIslandInputs(container, descriptor, inputs);
|
|
64
117
|
registerIslandParts(container, descriptor, islandLog);
|
|
65
118
|
return container;
|
|
66
119
|
} catch (error) {
|
|
@@ -166,14 +219,12 @@ function renderApp(descriptor, request) {
|
|
|
166
219
|
pathname: request.pathname,
|
|
167
220
|
search: (_b = request.search) != null ? _b : ""
|
|
168
221
|
};
|
|
169
|
-
const
|
|
222
|
+
const inputs = islandInputsOf(descriptor, request.inputs);
|
|
223
|
+
const container = createIslandContainer(descriptor, { context: request.context, inputs, parent: request.parent });
|
|
170
224
|
if (container === null) {
|
|
171
225
|
throw new Error(`den/island: \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \xAB${descriptor.name}\xBB \u043D\u0435 \u0441\u043E\u0431\u0440\u0430\u043B\u043E\u0441\u044C \u2014 \u0440\u0435\u043D\u0434\u0435\u0440 \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u0435\u043D`);
|
|
172
226
|
}
|
|
173
227
|
try {
|
|
174
|
-
if (request.context) {
|
|
175
|
-
container.bind(RequestContextToken).toValue(request.context);
|
|
176
|
-
}
|
|
177
228
|
yield activateIslandViewModels(container, descriptor, route);
|
|
178
229
|
const contribution = collectDocumentContribution(container, descriptor);
|
|
179
230
|
const { data, head, redirect, status = STATUS_OK } = contribution;
|
|
@@ -181,7 +232,7 @@ function renderApp(descriptor, request) {
|
|
|
181
232
|
return { data, head, html: "", redirect, state: {}, status };
|
|
182
233
|
}
|
|
183
234
|
const assets = (_c = contribution.assets) != null ? _c : descriptor.assets;
|
|
184
|
-
const state = collectIslandState(container, descriptor);
|
|
235
|
+
const state = __spreadValues(__spreadValues({}, inputs), collectIslandState(container, descriptor));
|
|
185
236
|
if (descriptor.view === void 0 || descriptor.viewLayer === void 0) {
|
|
186
237
|
return { assets, data, head, html: "", state, status };
|
|
187
238
|
}
|
|
@@ -231,6 +282,11 @@ function pathPattern(pattern) {
|
|
|
231
282
|
|
|
232
283
|
export {
|
|
233
284
|
isDocumentSource,
|
|
285
|
+
islandInputsOf,
|
|
286
|
+
bindIslandInputs,
|
|
287
|
+
parseCookieHeader,
|
|
288
|
+
browserRequestContext,
|
|
289
|
+
bindRequestContext,
|
|
234
290
|
getAppContainer,
|
|
235
291
|
createIslandContainer,
|
|
236
292
|
hydrateIslandState,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as DefineServiceOptions, S as ServiceDefinition, b as DefineViewModelOptions, V as ViewModelDefinition, D as DefineRepositoryOptions, d as RepositoryDefinition } from './types-
|
|
1
|
+
import { a as DefineServiceOptions, S as ServiceDefinition, b as DefineViewModelOptions, V as ViewModelDefinition, D as DefineRepositoryOptions, d as RepositoryDefinition } from './types-BxMQ-VOd.js';
|
|
2
2
|
import { Token } from '@foxford/ioc';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as DefineServiceOptions, S as ServiceDefinition, b as DefineViewModelOptions, V as ViewModelDefinition, D as DefineRepositoryOptions, d as RepositoryDefinition } from './types-
|
|
1
|
+
import { a as DefineServiceOptions, S as ServiceDefinition, b as DefineViewModelOptions, V as ViewModelDefinition, D as DefineRepositoryOptions, d as RepositoryDefinition } from './types-BxMQ-VOd.cjs';
|
|
2
2
|
import { Token } from '@foxford/ioc';
|
|
3
3
|
|
|
4
4
|
/**
|
package/define.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { d as defineRepository, a as defineService, b as defineViewModel } from './define-repository-
|
|
2
|
-
export { D as DefineSlotOptions, S as SlotDefinition, d as defineSlot } from './define-slot-
|
|
3
|
-
export { D as DefineRepositoryOptions, a as DefineServiceOptions, b as DefineViewModelOptions, c as Definition, d as RepositoryDefinition, S as ServiceDefinition, e as SlotEntry, f as SlotRegistry, g as SlotRegistryToken, V as ViewModelDefinition } from './types-
|
|
1
|
+
export { d as defineRepository, a as defineService, b as defineViewModel } from './define-repository-C0MI-J32.cjs';
|
|
2
|
+
export { D as DefineSlotOptions, S as SlotDefinition, d as defineSlot } from './define-slot-BEeHNEph.cjs';
|
|
3
|
+
export { D as DefineRepositoryOptions, a as DefineServiceOptions, b as DefineViewModelOptions, c as Definition, d as RepositoryDefinition, S as ServiceDefinition, e as SlotEntry, f as SlotRegistry, g as SlotRegistryToken, V as ViewModelDefinition } from './types-BxMQ-VOd.cjs';
|
|
4
4
|
import { Token, Container } from '@foxford/ioc';
|
|
5
5
|
import { HierarchicalLogger } from '@foxford/logger';
|
|
6
6
|
|
package/define.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { d as defineRepository, a as defineService, b as defineViewModel } from './define-repository-
|
|
2
|
-
export { D as DefineSlotOptions, S as SlotDefinition, d as defineSlot } from './define-slot-
|
|
3
|
-
export { D as DefineRepositoryOptions, a as DefineServiceOptions, b as DefineViewModelOptions, c as Definition, d as RepositoryDefinition, S as ServiceDefinition, e as SlotEntry, f as SlotRegistry, g as SlotRegistryToken, V as ViewModelDefinition } from './types-
|
|
1
|
+
export { d as defineRepository, a as defineService, b as defineViewModel } from './define-repository-AO7JI6Cb.js';
|
|
2
|
+
export { D as DefineSlotOptions, S as SlotDefinition, d as defineSlot } from './define-slot-CdWdFM16.js';
|
|
3
|
+
export { D as DefineRepositoryOptions, a as DefineServiceOptions, b as DefineViewModelOptions, c as Definition, d as RepositoryDefinition, S as ServiceDefinition, e as SlotEntry, f as SlotRegistry, g as SlotRegistryToken, V as ViewModelDefinition } from './types-BxMQ-VOd.js';
|
|
4
4
|
import { Token, Container } from '@foxford/ioc';
|
|
5
5
|
import { HierarchicalLogger } from '@foxford/logger';
|
|
6
6
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SlotDefinition } from './define-slot-
|
|
2
|
-
import { L as LayerDefinition, c as Definition } from './types-
|
|
1
|
+
import { S as SlotDefinition } from './define-slot-CdWdFM16.js';
|
|
2
|
+
import { L as LayerDefinition, c as Definition } from './types-BxMQ-VOd.js';
|
|
3
3
|
import { Token } from '@foxford/ioc';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -50,6 +50,18 @@ interface IslandDescriptor {
|
|
|
50
50
|
* ездит через denState.
|
|
51
51
|
*/
|
|
52
52
|
viewModels?: ReadonlyArray<Definition<unknown>>;
|
|
53
|
+
/**
|
|
54
|
+
* Что приложению нужно от хоста: токены из `@foxford/contracts` — посетитель, настройки
|
|
55
|
+
* площадки, конфиг транспорта, эксперименты.
|
|
56
|
+
*
|
|
57
|
+
* Заявку на данные закрывает ядро: объявленные токены биндятся в контейнер острова из
|
|
58
|
+
* входных данных хоста (на сервере из запроса, в браузере из состояния документа), и они
|
|
59
|
+
* едут одинаково обоими транспортами — аргументом `renderApp` в процессе хоста и телом
|
|
60
|
+
* запроса за сетью. Заявку на живой код (возможность другого приложения) закрывает
|
|
61
|
+
* исполнитель по своим правилам — по сети такое не ездит, ядро о ней не знает.
|
|
62
|
+
* Единицы читают полученное через свой `requires`. Не объявленное не биндится.
|
|
63
|
+
*/
|
|
64
|
+
requires?: ReadonlyArray<Token<unknown>>;
|
|
53
65
|
/**
|
|
54
66
|
* Единицы, которые обязаны жить с загрузки, а не с первого резолва.
|
|
55
67
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SlotDefinition } from './define-slot-
|
|
2
|
-
import { L as LayerDefinition, c as Definition } from './types-
|
|
1
|
+
import { S as SlotDefinition } from './define-slot-BEeHNEph.cjs';
|
|
2
|
+
import { L as LayerDefinition, c as Definition } from './types-BxMQ-VOd.cjs';
|
|
3
3
|
import { Token } from '@foxford/ioc';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -50,6 +50,18 @@ interface IslandDescriptor {
|
|
|
50
50
|
* ездит через denState.
|
|
51
51
|
*/
|
|
52
52
|
viewModels?: ReadonlyArray<Definition<unknown>>;
|
|
53
|
+
/**
|
|
54
|
+
* Что приложению нужно от хоста: токены из `@foxford/contracts` — посетитель, настройки
|
|
55
|
+
* площадки, конфиг транспорта, эксперименты.
|
|
56
|
+
*
|
|
57
|
+
* Заявку на данные закрывает ядро: объявленные токены биндятся в контейнер острова из
|
|
58
|
+
* входных данных хоста (на сервере из запроса, в браузере из состояния документа), и они
|
|
59
|
+
* едут одинаково обоими транспортами — аргументом `renderApp` в процессе хоста и телом
|
|
60
|
+
* запроса за сетью. Заявку на живой код (возможность другого приложения) закрывает
|
|
61
|
+
* исполнитель по своим правилам — по сети такое не ездит, ядро о ней не знает.
|
|
62
|
+
* Единицы читают полученное через свой `requires`. Не объявленное не биндится.
|
|
63
|
+
*/
|
|
64
|
+
requires?: ReadonlyArray<Token<unknown>>;
|
|
53
65
|
/**
|
|
54
66
|
* Единицы, которые обязаны жить с загрузки, а не с первого резолва.
|
|
55
67
|
*
|
package/index.d.cts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { C as Core,
|
|
2
|
-
export {
|
|
1
|
+
import { C as Core, j as ContainerManager, R as RequestContext, k as GuardRunner, l as Guard, m as GuardResult, N as NavigationManager, n as NavigationEntry, o as NavigationInterceptor, p as Disposable, q as LeaveGuardResult, r as StateSerializer, s as DefineGuardOptions, G as GuardDefinition, E as ExtensionConfig, t as DefineExtensionOptions, u as ExtensionDefinition, A as ActionGuard, v as DefineActionGuardOptions, w as ActionGuardDefinition, x as LayoutConfig, y as DefineLayoutOptions, z as LayoutDefinition, h as LayerConfig, B as DefineLayerOptions, L as LayerDefinition } from './types-BxMQ-VOd.cjs';
|
|
2
|
+
export { F as Activatable, H as ActivatableToken, I as ContainerManagerToken, D as DefineRepositoryOptions, a as DefineServiceOptions, b as DefineViewModelOptions, c as Definition, J as GuardRunnerToken, K as NavigationManagerToken, d as RepositoryDefinition, i as RequestContextToken, S as ServiceDefinition, e as SlotEntry, f as SlotRegistry, g as SlotRegistryToken, M as StateCache, O as StateParticipant, P as StateRegistry, Q as StateRegistryToken, T as StateSerializerToken, V as ViewModelDefinition } from './types-BxMQ-VOd.cjs';
|
|
3
3
|
import { Container, Token } from '@foxford/ioc';
|
|
4
4
|
import { DefinitionResolver } from './adapter.cjs';
|
|
5
|
-
export { d as defineRepository, a as defineService, b as defineViewModel } from './define-repository-
|
|
6
|
-
export { D as DefineSlotOptions, S as SlotDefinition, d as defineSlot } from './define-slot-
|
|
7
|
-
export { V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken } from './view-adapter-
|
|
8
|
-
import './descriptor-
|
|
5
|
+
export { d as defineRepository, a as defineService, b as defineViewModel } from './define-repository-C0MI-J32.cjs';
|
|
6
|
+
export { D as DefineSlotOptions, S as SlotDefinition, d as defineSlot } from './define-slot-BEeHNEph.cjs';
|
|
7
|
+
export { V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken } from './view-adapter-DMLlp3Iu.cjs';
|
|
8
|
+
import './descriptor-C2j6Zz6c.cjs';
|
|
9
9
|
import './server-render-CocWXQKC.cjs';
|
|
10
10
|
|
|
11
11
|
/**
|
package/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { C as Core,
|
|
2
|
-
export {
|
|
1
|
+
import { C as Core, j as ContainerManager, R as RequestContext, k as GuardRunner, l as Guard, m as GuardResult, N as NavigationManager, n as NavigationEntry, o as NavigationInterceptor, p as Disposable, q as LeaveGuardResult, r as StateSerializer, s as DefineGuardOptions, G as GuardDefinition, E as ExtensionConfig, t as DefineExtensionOptions, u as ExtensionDefinition, A as ActionGuard, v as DefineActionGuardOptions, w as ActionGuardDefinition, x as LayoutConfig, y as DefineLayoutOptions, z as LayoutDefinition, h as LayerConfig, B as DefineLayerOptions, L as LayerDefinition } from './types-BxMQ-VOd.js';
|
|
2
|
+
export { F as Activatable, H as ActivatableToken, I as ContainerManagerToken, D as DefineRepositoryOptions, a as DefineServiceOptions, b as DefineViewModelOptions, c as Definition, J as GuardRunnerToken, K as NavigationManagerToken, d as RepositoryDefinition, i as RequestContextToken, S as ServiceDefinition, e as SlotEntry, f as SlotRegistry, g as SlotRegistryToken, M as StateCache, O as StateParticipant, P as StateRegistry, Q as StateRegistryToken, T as StateSerializerToken, V as ViewModelDefinition } from './types-BxMQ-VOd.js';
|
|
3
3
|
import { Container, Token } from '@foxford/ioc';
|
|
4
4
|
import { DefinitionResolver } from './adapter.js';
|
|
5
|
-
export { d as defineRepository, a as defineService, b as defineViewModel } from './define-repository-
|
|
6
|
-
export { D as DefineSlotOptions, S as SlotDefinition, d as defineSlot } from './define-slot-
|
|
7
|
-
export { V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken } from './view-adapter-
|
|
8
|
-
import './descriptor-
|
|
5
|
+
export { d as defineRepository, a as defineService, b as defineViewModel } from './define-repository-AO7JI6Cb.js';
|
|
6
|
+
export { D as DefineSlotOptions, S as SlotDefinition, d as defineSlot } from './define-slot-CdWdFM16.js';
|
|
7
|
+
export { V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken } from './view-adapter-DNLRSFka.js';
|
|
8
|
+
import './descriptor-BSaHM5B4.js';
|
|
9
9
|
import './server-render-CocWXQKC.js';
|
|
10
10
|
|
|
11
11
|
/**
|
package/island/index.cjs
CHANGED
|
@@ -11,13 +11,20 @@
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
var _chunkJMRHLOBDcjs = require('../chunk-JMRHLOBD.cjs');
|
|
15
20
|
|
|
16
21
|
|
|
17
22
|
|
|
18
23
|
|
|
19
24
|
var _chunkXOJ2VWX4cjs = require('../chunk-XOJ2VWX4.cjs');
|
|
20
|
-
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
var _chunk6QV4L6R2cjs = require('../chunk-6QV4L6R2.cjs');
|
|
21
28
|
require('../chunk-A6ZPAM6Z.cjs');
|
|
22
29
|
|
|
23
30
|
|
|
@@ -139,4 +146,10 @@ function describeIsland(descriptor, denState) {
|
|
|
139
146
|
|
|
140
147
|
|
|
141
148
|
|
|
142
|
-
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
exports.DOCUMENT_EVENT = DOCUMENT_EVENT; exports.ISLAND_ERRORS_KEY = ISLAND_ERRORS_KEY; exports.NAVIGATE_EVENT = NAVIGATE_EVENT; exports.RequestContextToken = _chunk6QV4L6R2cjs.RequestContextToken; exports.ViewLayerToken = _chunkXOJ2VWX4cjs.ViewLayerToken; exports.activateIslandViewModels = _chunkJMRHLOBDcjs.activateIslandViewModels; exports.bindIslandInputs = _chunkJMRHLOBDcjs.bindIslandInputs; exports.bindRequestContext = _chunkJMRHLOBDcjs.bindRequestContext; exports.browserRequestContext = _chunkJMRHLOBDcjs.browserRequestContext; exports.collectDocumentContribution = _chunkJMRHLOBDcjs.collectDocumentContribution; exports.collectIslandState = _chunkJMRHLOBDcjs.collectIslandState; exports.createIslandContainer = _chunkJMRHLOBDcjs.createIslandContainer; exports.describeIsland = describeIsland; exports.getAppContainer = _chunkJMRHLOBDcjs.getAppContainer; exports.getIslandsSnapshot = getIslandsSnapshot; exports.hydrateIslandState = _chunkJMRHLOBDcjs.hydrateIslandState; exports.isDocumentSource = _chunkJMRHLOBDcjs.isDocumentSource; exports.islandInputsOf = _chunkJMRHLOBDcjs.islandInputsOf; exports.matchRoute = _chunkJMRHLOBDcjs.matchRoute; exports.navigateIsland = navigateIsland; exports.normalizeRoutes = _chunkJMRHLOBDcjs.normalizeRoutes; exports.onIslandDocument = onIslandDocument; exports.onIslandNavigate = onIslandNavigate; exports.parseCookieHeader = _chunkJMRHLOBDcjs.parseCookieHeader; exports.pathPattern = _chunkJMRHLOBDcjs.pathPattern; exports.publishIslandDocument = publishIslandDocument; exports.registerIsland = registerIsland; exports.renderApp = _chunkJMRHLOBDcjs.renderApp; exports.reportIslandError = reportIslandError; exports.resolveEagerUnits = _chunkJMRHLOBDcjs.resolveEagerUnits; exports.resolveViewAdapter = _chunkXOJ2VWX4cjs.resolveViewAdapter; exports.slotAddress = slotAddress; exports.subscribeIslands = subscribeIslands; exports.viewAdapterOf = _chunkXOJ2VWX4cjs.viewAdapterOf;
|
package/island/index.d.cts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { A as AppAssets, I as IslandDescriptor } from '../descriptor-
|
|
1
|
+
import { A as AppAssets, I as IslandDescriptor } from '../descriptor-C2j6Zz6c.cjs';
|
|
2
|
+
import { R as RequestContext } from '../types-BxMQ-VOd.cjs';
|
|
3
|
+
export { i as RequestContextToken } from '../types-BxMQ-VOd.cjs';
|
|
2
4
|
import { Container } from '@foxford/ioc';
|
|
3
|
-
|
|
4
|
-
export { A as AppRoute, R as RouteDeclaration, a as RouteMatch, m as matchRoute, n as normalizeRoutes, p as pathPattern } from '../routes-B0hDrkiF.cjs';
|
|
5
|
+
export { A as AppRoute, R as RouteDeclaration, a as RouteMatch, m as matchRoute, n as normalizeRoutes, p as pathPattern } from '../routes-BvV405k4.cjs';
|
|
5
6
|
export { R as RenderTree, a as ServerRender, S as ServerRenderResult } from '../server-render-CocWXQKC.cjs';
|
|
6
|
-
export { R as RenderIslandOptions, V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken, r as resolveViewAdapter, v as viewAdapterOf } from '../view-adapter-
|
|
7
|
-
import '../define-slot-
|
|
7
|
+
export { R as RenderIslandOptions, V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken, r as resolveViewAdapter, v as viewAdapterOf } from '../view-adapter-DMLlp3Iu.cjs';
|
|
8
|
+
import '../define-slot-BEeHNEph.cjs';
|
|
8
9
|
|
|
9
10
|
/** Вклад приложения в `<head>` документа. */
|
|
10
11
|
interface DocumentHead {
|
|
@@ -124,6 +125,18 @@ interface CreateIslandContainerOptions {
|
|
|
124
125
|
* сервисы. Хост биндит их один раз в app-контейнер, а резолв поднимается по parent-chain.
|
|
125
126
|
*/
|
|
126
127
|
parent?: Container;
|
|
128
|
+
/**
|
|
129
|
+
* Реквизиты запроса — заголовки и куки. На сервере их даёт исполнитель (хост либо сетевой
|
|
130
|
+
* рантайм из `X-Forwarded-*`), в браузере адаптер берёт их из документа. Биндятся под
|
|
131
|
+
* `RequestContextToken` до регистрации единиц, поэтому единица вправе их требовать на
|
|
132
|
+
* обеих сторонах.
|
|
133
|
+
*/
|
|
134
|
+
context?: RequestContext;
|
|
135
|
+
/**
|
|
136
|
+
* Входные данные хоста по ключу `token.description` — биндятся те, что дескриптор объявил
|
|
137
|
+
* в `requires`. На сервере — из запроса, в браузере — из состояния документа.
|
|
138
|
+
*/
|
|
139
|
+
inputs?: Record<string, unknown>;
|
|
127
140
|
}
|
|
128
141
|
/**
|
|
129
142
|
* Собирает контейнер острова: scope-логгер, биндинги хоста, регистрация units + VM + слотов.
|
|
@@ -240,6 +253,43 @@ declare function publishIslandDocument(node: EventTarget, contribution: Document
|
|
|
240
253
|
*/
|
|
241
254
|
declare function onIslandDocument(node: EventTarget, onDocument: (contribution: DocumentContribution) => void): () => void;
|
|
242
255
|
|
|
256
|
+
/**
|
|
257
|
+
* Входные данные, объявленные дескриптором, из переданного набора.
|
|
258
|
+
*
|
|
259
|
+
* @param descriptor - Дескриптор острова
|
|
260
|
+
* @param source - Набор по ключу `token.description`: тело запроса либо состояние документа
|
|
261
|
+
* @returns Только объявленные и присутствующие ключи
|
|
262
|
+
*/
|
|
263
|
+
declare function islandInputsOf(descriptor: IslandDescriptor, source: Record<string, unknown> | undefined): Record<string, unknown>;
|
|
264
|
+
/**
|
|
265
|
+
* Биндит входные данные в контейнер острова под объявленными токенами.
|
|
266
|
+
*
|
|
267
|
+
* Не присланное не биндится: единица, которая требует такой токен, упадёт на резолве, и это
|
|
268
|
+
* честный отказ — хост не отдал то, без чего приложение работать не обязано.
|
|
269
|
+
*
|
|
270
|
+
* @param container - Контейнер острова
|
|
271
|
+
* @param descriptor - Дескриптор острова
|
|
272
|
+
* @param inputs - Входные данные по ключу `token.description`
|
|
273
|
+
*/
|
|
274
|
+
declare function bindIslandInputs(container: Container, descriptor: IslandDescriptor, inputs: Record<string, unknown> | undefined): void;
|
|
275
|
+
/** Разбирает `Cookie` в карту. Дубли: побеждает первый, как и в браузере. */
|
|
276
|
+
declare function parseCookieHeader(header: string | undefined): Record<string, string>;
|
|
277
|
+
/**
|
|
278
|
+
* Реквизиты запроса в браузере: куки документа, заголовков нет.
|
|
279
|
+
*
|
|
280
|
+
* Биндится в контейнер острова при сборке, чтобы единица, требующая `RequestContextToken`,
|
|
281
|
+
* резолвилась на обеих сторонах одинаково; иначе приложению пришлось бы держать две
|
|
282
|
+
* реализации и переключать их по среде.
|
|
283
|
+
*/
|
|
284
|
+
declare function browserRequestContext(): RequestContext;
|
|
285
|
+
/**
|
|
286
|
+
* Биндит реквизиты запроса в контейнер острова.
|
|
287
|
+
*
|
|
288
|
+
* @param container - Контейнер острова
|
|
289
|
+
* @param context - Реквизиты: серверные из `X-Forwarded-*`, браузерные из документа
|
|
290
|
+
*/
|
|
291
|
+
declare function bindRequestContext(container: Container, context: RequestContext | undefined): void;
|
|
292
|
+
|
|
243
293
|
/** Запрос на рендер приложения. */
|
|
244
294
|
interface RenderAppRequest {
|
|
245
295
|
/** Путь без search, с ведущим слэшем: `/legal/general`. */
|
|
@@ -254,6 +304,12 @@ interface RenderAppRequest {
|
|
|
254
304
|
* транспортов: в процессе хоста их даёт хост, за сетью — сетевой рантайм из `X-Forwarded-*`.
|
|
255
305
|
*/
|
|
256
306
|
context?: RequestContext;
|
|
307
|
+
/**
|
|
308
|
+
* Входные данные хоста по ключу `token.description`: посетитель, настройки, эксперименты.
|
|
309
|
+
* В контейнер попадают только те, что дескриптор объявил в `requires`; они же уезжают в
|
|
310
|
+
* состояние ответа, чтобы остров в браузере получил их вместе с состоянием VM.
|
|
311
|
+
*/
|
|
312
|
+
inputs?: Record<string, unknown>;
|
|
257
313
|
/**
|
|
258
314
|
* Родитель контейнера приложения: через него приезжает всё, что настроил исполнитель, —
|
|
259
315
|
* логгер, конфиг HTTP, выданные возможности. По умолчанию — app-scope контейнер.
|
|
@@ -356,4 +412,4 @@ declare function getAppContainer(): Container;
|
|
|
356
412
|
*/
|
|
357
413
|
declare function slotAddress(app: string, slot: string): string;
|
|
358
414
|
|
|
359
|
-
export { AppAssets, type CreateIslandContainerOptions, DOCUMENT_EVENT, type DocumentContribution, type DocumentHead, type DocumentSource, ISLAND_ERRORS_KEY, IslandDescriptor, type IslandErrorContext, type IslandErrorPhase, type IslandErrorReport, type IslandRecord, type IslandRoute, NAVIGATE_EVENT, type RenderAppRequest, type RenderAppResult, activateIslandViewModels, collectDocumentContribution, collectIslandState, createIslandContainer, describeIsland, getAppContainer, getIslandsSnapshot, hydrateIslandState, isDocumentSource, navigateIsland, onIslandDocument, onIslandNavigate, publishIslandDocument, registerIsland, renderApp, reportIslandError, resolveEagerUnits, slotAddress, subscribeIslands };
|
|
415
|
+
export { AppAssets, type CreateIslandContainerOptions, DOCUMENT_EVENT, type DocumentContribution, type DocumentHead, type DocumentSource, ISLAND_ERRORS_KEY, IslandDescriptor, type IslandErrorContext, type IslandErrorPhase, type IslandErrorReport, type IslandRecord, type IslandRoute, NAVIGATE_EVENT, type RenderAppRequest, type RenderAppResult, RequestContext, activateIslandViewModels, bindIslandInputs, bindRequestContext, browserRequestContext, collectDocumentContribution, collectIslandState, createIslandContainer, describeIsland, getAppContainer, getIslandsSnapshot, hydrateIslandState, isDocumentSource, islandInputsOf, navigateIsland, onIslandDocument, onIslandNavigate, parseCookieHeader, publishIslandDocument, registerIsland, renderApp, reportIslandError, resolveEagerUnits, slotAddress, subscribeIslands };
|
package/island/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { A as AppAssets, I as IslandDescriptor } from '../descriptor-
|
|
1
|
+
import { A as AppAssets, I as IslandDescriptor } from '../descriptor-BSaHM5B4.js';
|
|
2
|
+
import { R as RequestContext } from '../types-BxMQ-VOd.js';
|
|
3
|
+
export { i as RequestContextToken } from '../types-BxMQ-VOd.js';
|
|
2
4
|
import { Container } from '@foxford/ioc';
|
|
3
|
-
|
|
4
|
-
export { A as AppRoute, R as RouteDeclaration, a as RouteMatch, m as matchRoute, n as normalizeRoutes, p as pathPattern } from '../routes-0uXJ0fux.js';
|
|
5
|
+
export { A as AppRoute, R as RouteDeclaration, a as RouteMatch, m as matchRoute, n as normalizeRoutes, p as pathPattern } from '../routes-Di3K_0uQ.js';
|
|
5
6
|
export { R as RenderTree, a as ServerRender, S as ServerRenderResult } from '../server-render-CocWXQKC.js';
|
|
6
|
-
export { R as RenderIslandOptions, V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken, r as resolveViewAdapter, v as viewAdapterOf } from '../view-adapter-
|
|
7
|
-
import '../define-slot-
|
|
7
|
+
export { R as RenderIslandOptions, V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken, r as resolveViewAdapter, v as viewAdapterOf } from '../view-adapter-DNLRSFka.js';
|
|
8
|
+
import '../define-slot-CdWdFM16.js';
|
|
8
9
|
|
|
9
10
|
/** Вклад приложения в `<head>` документа. */
|
|
10
11
|
interface DocumentHead {
|
|
@@ -124,6 +125,18 @@ interface CreateIslandContainerOptions {
|
|
|
124
125
|
* сервисы. Хост биндит их один раз в app-контейнер, а резолв поднимается по parent-chain.
|
|
125
126
|
*/
|
|
126
127
|
parent?: Container;
|
|
128
|
+
/**
|
|
129
|
+
* Реквизиты запроса — заголовки и куки. На сервере их даёт исполнитель (хост либо сетевой
|
|
130
|
+
* рантайм из `X-Forwarded-*`), в браузере адаптер берёт их из документа. Биндятся под
|
|
131
|
+
* `RequestContextToken` до регистрации единиц, поэтому единица вправе их требовать на
|
|
132
|
+
* обеих сторонах.
|
|
133
|
+
*/
|
|
134
|
+
context?: RequestContext;
|
|
135
|
+
/**
|
|
136
|
+
* Входные данные хоста по ключу `token.description` — биндятся те, что дескриптор объявил
|
|
137
|
+
* в `requires`. На сервере — из запроса, в браузере — из состояния документа.
|
|
138
|
+
*/
|
|
139
|
+
inputs?: Record<string, unknown>;
|
|
127
140
|
}
|
|
128
141
|
/**
|
|
129
142
|
* Собирает контейнер острова: scope-логгер, биндинги хоста, регистрация units + VM + слотов.
|
|
@@ -240,6 +253,43 @@ declare function publishIslandDocument(node: EventTarget, contribution: Document
|
|
|
240
253
|
*/
|
|
241
254
|
declare function onIslandDocument(node: EventTarget, onDocument: (contribution: DocumentContribution) => void): () => void;
|
|
242
255
|
|
|
256
|
+
/**
|
|
257
|
+
* Входные данные, объявленные дескриптором, из переданного набора.
|
|
258
|
+
*
|
|
259
|
+
* @param descriptor - Дескриптор острова
|
|
260
|
+
* @param source - Набор по ключу `token.description`: тело запроса либо состояние документа
|
|
261
|
+
* @returns Только объявленные и присутствующие ключи
|
|
262
|
+
*/
|
|
263
|
+
declare function islandInputsOf(descriptor: IslandDescriptor, source: Record<string, unknown> | undefined): Record<string, unknown>;
|
|
264
|
+
/**
|
|
265
|
+
* Биндит входные данные в контейнер острова под объявленными токенами.
|
|
266
|
+
*
|
|
267
|
+
* Не присланное не биндится: единица, которая требует такой токен, упадёт на резолве, и это
|
|
268
|
+
* честный отказ — хост не отдал то, без чего приложение работать не обязано.
|
|
269
|
+
*
|
|
270
|
+
* @param container - Контейнер острова
|
|
271
|
+
* @param descriptor - Дескриптор острова
|
|
272
|
+
* @param inputs - Входные данные по ключу `token.description`
|
|
273
|
+
*/
|
|
274
|
+
declare function bindIslandInputs(container: Container, descriptor: IslandDescriptor, inputs: Record<string, unknown> | undefined): void;
|
|
275
|
+
/** Разбирает `Cookie` в карту. Дубли: побеждает первый, как и в браузере. */
|
|
276
|
+
declare function parseCookieHeader(header: string | undefined): Record<string, string>;
|
|
277
|
+
/**
|
|
278
|
+
* Реквизиты запроса в браузере: куки документа, заголовков нет.
|
|
279
|
+
*
|
|
280
|
+
* Биндится в контейнер острова при сборке, чтобы единица, требующая `RequestContextToken`,
|
|
281
|
+
* резолвилась на обеих сторонах одинаково; иначе приложению пришлось бы держать две
|
|
282
|
+
* реализации и переключать их по среде.
|
|
283
|
+
*/
|
|
284
|
+
declare function browserRequestContext(): RequestContext;
|
|
285
|
+
/**
|
|
286
|
+
* Биндит реквизиты запроса в контейнер острова.
|
|
287
|
+
*
|
|
288
|
+
* @param container - Контейнер острова
|
|
289
|
+
* @param context - Реквизиты: серверные из `X-Forwarded-*`, браузерные из документа
|
|
290
|
+
*/
|
|
291
|
+
declare function bindRequestContext(container: Container, context: RequestContext | undefined): void;
|
|
292
|
+
|
|
243
293
|
/** Запрос на рендер приложения. */
|
|
244
294
|
interface RenderAppRequest {
|
|
245
295
|
/** Путь без search, с ведущим слэшем: `/legal/general`. */
|
|
@@ -254,6 +304,12 @@ interface RenderAppRequest {
|
|
|
254
304
|
* транспортов: в процессе хоста их даёт хост, за сетью — сетевой рантайм из `X-Forwarded-*`.
|
|
255
305
|
*/
|
|
256
306
|
context?: RequestContext;
|
|
307
|
+
/**
|
|
308
|
+
* Входные данные хоста по ключу `token.description`: посетитель, настройки, эксперименты.
|
|
309
|
+
* В контейнер попадают только те, что дескриптор объявил в `requires`; они же уезжают в
|
|
310
|
+
* состояние ответа, чтобы остров в браузере получил их вместе с состоянием VM.
|
|
311
|
+
*/
|
|
312
|
+
inputs?: Record<string, unknown>;
|
|
257
313
|
/**
|
|
258
314
|
* Родитель контейнера приложения: через него приезжает всё, что настроил исполнитель, —
|
|
259
315
|
* логгер, конфиг HTTP, выданные возможности. По умолчанию — app-scope контейнер.
|
|
@@ -356,4 +412,4 @@ declare function getAppContainer(): Container;
|
|
|
356
412
|
*/
|
|
357
413
|
declare function slotAddress(app: string, slot: string): string;
|
|
358
414
|
|
|
359
|
-
export { AppAssets, type CreateIslandContainerOptions, DOCUMENT_EVENT, type DocumentContribution, type DocumentHead, type DocumentSource, ISLAND_ERRORS_KEY, IslandDescriptor, type IslandErrorContext, type IslandErrorPhase, type IslandErrorReport, type IslandRecord, type IslandRoute, NAVIGATE_EVENT, type RenderAppRequest, type RenderAppResult, activateIslandViewModels, collectDocumentContribution, collectIslandState, createIslandContainer, describeIsland, getAppContainer, getIslandsSnapshot, hydrateIslandState, isDocumentSource, navigateIsland, onIslandDocument, onIslandNavigate, publishIslandDocument, registerIsland, renderApp, reportIslandError, resolveEagerUnits, slotAddress, subscribeIslands };
|
|
415
|
+
export { AppAssets, type CreateIslandContainerOptions, DOCUMENT_EVENT, type DocumentContribution, type DocumentHead, type DocumentSource, ISLAND_ERRORS_KEY, IslandDescriptor, type IslandErrorContext, type IslandErrorPhase, type IslandErrorReport, type IslandRecord, type IslandRoute, NAVIGATE_EVENT, type RenderAppRequest, type RenderAppResult, RequestContext, activateIslandViewModels, bindIslandInputs, bindRequestContext, browserRequestContext, collectDocumentContribution, collectIslandState, createIslandContainer, describeIsland, getAppContainer, getIslandsSnapshot, hydrateIslandState, isDocumentSource, islandInputsOf, navigateIsland, onIslandDocument, onIslandNavigate, parseCookieHeader, publishIslandDocument, registerIsland, renderApp, reportIslandError, resolveEagerUnits, slotAddress, subscribeIslands };
|
package/island/index.js
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
2
|
activateIslandViewModels,
|
|
3
|
+
bindIslandInputs,
|
|
4
|
+
bindRequestContext,
|
|
5
|
+
browserRequestContext,
|
|
3
6
|
collectDocumentContribution,
|
|
4
7
|
collectIslandState,
|
|
5
8
|
createIslandContainer,
|
|
6
9
|
getAppContainer,
|
|
7
10
|
hydrateIslandState,
|
|
8
11
|
isDocumentSource,
|
|
12
|
+
islandInputsOf,
|
|
9
13
|
matchRoute,
|
|
10
14
|
normalizeRoutes,
|
|
15
|
+
parseCookieHeader,
|
|
11
16
|
pathPattern,
|
|
12
17
|
renderApp,
|
|
13
18
|
resolveEagerUnits
|
|
14
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-VO3ORM7Z.js";
|
|
15
20
|
import {
|
|
16
21
|
ViewLayerToken,
|
|
17
22
|
resolveViewAdapter,
|
|
18
23
|
viewAdapterOf
|
|
19
24
|
} from "../chunk-E23E2VUC.js";
|
|
20
|
-
import
|
|
25
|
+
import {
|
|
26
|
+
RequestContextToken
|
|
27
|
+
} from "../chunk-3RX2OSUL.js";
|
|
21
28
|
import "../chunk-TPBI6TOU.js";
|
|
22
29
|
import {
|
|
23
30
|
__spreadValues
|
|
@@ -114,8 +121,12 @@ export {
|
|
|
114
121
|
DOCUMENT_EVENT,
|
|
115
122
|
ISLAND_ERRORS_KEY,
|
|
116
123
|
NAVIGATE_EVENT,
|
|
124
|
+
RequestContextToken,
|
|
117
125
|
ViewLayerToken,
|
|
118
126
|
activateIslandViewModels,
|
|
127
|
+
bindIslandInputs,
|
|
128
|
+
bindRequestContext,
|
|
129
|
+
browserRequestContext,
|
|
119
130
|
collectDocumentContribution,
|
|
120
131
|
collectIslandState,
|
|
121
132
|
createIslandContainer,
|
|
@@ -124,11 +135,13 @@ export {
|
|
|
124
135
|
getIslandsSnapshot,
|
|
125
136
|
hydrateIslandState,
|
|
126
137
|
isDocumentSource,
|
|
138
|
+
islandInputsOf,
|
|
127
139
|
matchRoute,
|
|
128
140
|
navigateIsland,
|
|
129
141
|
normalizeRoutes,
|
|
130
142
|
onIslandDocument,
|
|
131
143
|
onIslandNavigate,
|
|
144
|
+
parseCookieHeader,
|
|
132
145
|
pathPattern,
|
|
133
146
|
publishIslandDocument,
|
|
134
147
|
registerIsland,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@foxford/den",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"description": "Den — декларативный метафреймворк Foxford (core runtime)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"foxford",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"den": "./den.js"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"fastify": "^5.
|
|
33
|
+
"fastify": "^5.12.1",
|
|
34
34
|
"@foxford/ioc": "^1.1.2",
|
|
35
35
|
"@foxford/logger": "^1.2.2"
|
|
36
36
|
},
|
|
@@ -99,41 +99,41 @@
|
|
|
99
99
|
"chunk-E56BKBQZ.js",
|
|
100
100
|
"chunk-G6RT4EBO.cjs",
|
|
101
101
|
"chunk-H5DKRHHQ.cjs",
|
|
102
|
+
"chunk-JMRHLOBD.cjs",
|
|
102
103
|
"chunk-KQAB6C6Q.cjs",
|
|
103
104
|
"chunk-RG7ZV5BD.js",
|
|
104
|
-
"chunk-SOH2TL2N.js",
|
|
105
105
|
"chunk-T5QVCXVB.cjs",
|
|
106
106
|
"chunk-TPBI6TOU.js",
|
|
107
|
+
"chunk-VO3ORM7Z.js",
|
|
107
108
|
"chunk-WBHHHICS.js",
|
|
108
|
-
"chunk-XDM6J4LJ.cjs",
|
|
109
109
|
"chunk-XOJ2VWX4.cjs",
|
|
110
|
-
"define-repository-
|
|
111
|
-
"define-repository-
|
|
112
|
-
"define-slot-
|
|
113
|
-
"define-slot-
|
|
110
|
+
"define-repository-AO7JI6Cb.d.ts",
|
|
111
|
+
"define-repository-C0MI-J32.d.cts",
|
|
112
|
+
"define-slot-BEeHNEph.d.cts",
|
|
113
|
+
"define-slot-CdWdFM16.d.ts",
|
|
114
114
|
"define.cjs",
|
|
115
115
|
"define.d.cts",
|
|
116
116
|
"define.d.ts",
|
|
117
117
|
"define.js",
|
|
118
118
|
"den.js",
|
|
119
|
-
"descriptor-
|
|
120
|
-
"descriptor-
|
|
119
|
+
"descriptor-BSaHM5B4.d.ts",
|
|
120
|
+
"descriptor-C2j6Zz6c.d.cts",
|
|
121
121
|
"index.cjs",
|
|
122
122
|
"index.d.cts",
|
|
123
123
|
"index.d.ts",
|
|
124
124
|
"index.js",
|
|
125
125
|
"island",
|
|
126
126
|
"package.json",
|
|
127
|
-
"routes-
|
|
128
|
-
"routes-
|
|
127
|
+
"routes-BvV405k4.d.cts",
|
|
128
|
+
"routes-Di3K_0uQ.d.ts",
|
|
129
129
|
"serve",
|
|
130
130
|
"server-render-CocWXQKC.d.cts",
|
|
131
131
|
"server-render-CocWXQKC.d.ts",
|
|
132
|
-
"types-
|
|
133
|
-
"types-
|
|
134
|
-
"view-adapter-
|
|
135
|
-
"view-adapter-
|
|
132
|
+
"types-BxMQ-VOd.d.cts",
|
|
133
|
+
"types-BxMQ-VOd.d.ts",
|
|
134
|
+
"view-adapter-DMLlp3Iu.d.cts",
|
|
135
|
+
"view-adapter-DNLRSFka.d.ts"
|
|
136
136
|
],
|
|
137
|
-
"sha": "
|
|
137
|
+
"sha": "a0e9213",
|
|
138
138
|
"scripts": {}
|
|
139
139
|
}
|
package/serve/index.cjs
CHANGED
|
@@ -5,7 +5,8 @@ var _chunkKQAB6C6Qcjs = require('../chunk-KQAB6C6Q.cjs');
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
var _chunkJMRHLOBDcjs = require('../chunk-JMRHLOBD.cjs');
|
|
9
10
|
require('../chunk-XOJ2VWX4.cjs');
|
|
10
11
|
require('../chunk-6QV4L6R2.cjs');
|
|
11
12
|
|
|
@@ -69,28 +70,14 @@ function registerAssets(instance, source) {
|
|
|
69
70
|
|
|
70
71
|
var DEFAULT_SLOW_RENDER_MS = 1e3;
|
|
71
72
|
function claim(app) {
|
|
72
|
-
return
|
|
73
|
+
return _chunkJMRHLOBDcjs.normalizeRoutes.call(void 0, app.routes).map((route) => route.source);
|
|
73
74
|
}
|
|
74
75
|
function matchClaim(app, pathname) {
|
|
75
76
|
var _a, _b;
|
|
76
77
|
if (claim(app).length === 0) {
|
|
77
78
|
return {};
|
|
78
79
|
}
|
|
79
|
-
return (_b = (_a =
|
|
80
|
-
}
|
|
81
|
-
function parseCookies(header) {
|
|
82
|
-
const cookies = {};
|
|
83
|
-
for (const part of (header != null ? header : "").split(";")) {
|
|
84
|
-
const eq = part.indexOf("=");
|
|
85
|
-
if (eq < 1) {
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
const name = part.slice(0, eq).trim();
|
|
89
|
-
if (name && !(name in cookies)) {
|
|
90
|
-
cookies[name] = part.slice(eq + 1).trim();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return cookies;
|
|
80
|
+
return (_b = (_a = _chunkJMRHLOBDcjs.matchRoute.call(void 0, app.routes, pathname)) == null ? void 0 : _a.params) != null ? _b : null;
|
|
94
81
|
}
|
|
95
82
|
function browserContext(req) {
|
|
96
83
|
const headers = {};
|
|
@@ -107,7 +94,7 @@ function browserContext(req) {
|
|
|
107
94
|
if (typeof cookie === "string" && cookie !== "") {
|
|
108
95
|
headers.cookie = cookie;
|
|
109
96
|
}
|
|
110
|
-
return { cookies:
|
|
97
|
+
return { cookies: _chunkJMRHLOBDcjs.parseCookieHeader.call(void 0, cookie), headers };
|
|
111
98
|
}
|
|
112
99
|
var appPlugin = (instance, options) => {
|
|
113
100
|
var _a, _b;
|
|
@@ -119,30 +106,50 @@ var appPlugin = (instance, options) => {
|
|
|
119
106
|
void reply.header("cache-control", "no-store");
|
|
120
107
|
return claim(app);
|
|
121
108
|
});
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
const { pathname, search } = new URL(target, "http://localhost");
|
|
128
|
-
const params = matchClaim(app, pathname);
|
|
129
|
-
if (params === null) {
|
|
130
|
-
serveLog.error(`\u043F\u0443\u0442\u044C \xAB${pathname}\xBB \u0432\u043D\u0435 \u0437\u0430\u044F\u0432\u043A\u0438 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F`);
|
|
131
|
-
return reply.code(404).send({ error: `\u043F\u0443\u0442\u044C \xAB${pathname}\xBB \u0432\u043D\u0435 \u0437\u0430\u044F\u0432\u043A\u0438 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F` });
|
|
132
|
-
}
|
|
133
|
-
const startedAt = Date.now();
|
|
134
|
-
try {
|
|
135
|
-
const result = yield _chunkXDM6J4LJcjs.renderApp.call(void 0, app, { context: browserContext(req), params, pathname, search });
|
|
136
|
-
const elapsed = Date.now() - startedAt;
|
|
137
|
-
if (elapsed >= slowRenderMs) {
|
|
138
|
-
serveLog.warn(`\u043C\u0435\u0434\u043B\u0435\u043D\u043D\u044B\u0439 \u0440\u0435\u043D\u0434\u0435\u0440 \xAB${pathname}\xBB: ${String(elapsed)}\u043C\u0441`);
|
|
109
|
+
function handleRender(req, reply, target, inputs) {
|
|
110
|
+
return _chunkT5QVCXVBcjs.__async.call(void 0, this, null, function* () {
|
|
111
|
+
if (typeof target !== "string" || !target.startsWith("/")) {
|
|
112
|
+
return reply.code(400).send({ error: "\u043D\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u043D \u0438\u043B\u0438 \u043D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440 url" });
|
|
139
113
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
114
|
+
if (inputs !== void 0 && (typeof inputs !== "object" || inputs === null || Array.isArray(inputs))) {
|
|
115
|
+
return reply.code(400).send({ error: "inputs \u0434\u043E\u043B\u0436\u043D\u044B \u0431\u044B\u0442\u044C \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u043C \u043F\u043E \u043A\u043B\u044E\u0447\u0443 token.description" });
|
|
116
|
+
}
|
|
117
|
+
const { pathname, search } = new URL(target, "http://localhost");
|
|
118
|
+
const params = matchClaim(app, pathname);
|
|
119
|
+
if (params === null) {
|
|
120
|
+
serveLog.error(`\u043F\u0443\u0442\u044C \xAB${pathname}\xBB \u0432\u043D\u0435 \u0437\u0430\u044F\u0432\u043A\u0438 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F`);
|
|
121
|
+
return reply.code(404).send({ error: `\u043F\u0443\u0442\u044C \xAB${pathname}\xBB \u0432\u043D\u0435 \u0437\u0430\u044F\u0432\u043A\u0438 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F` });
|
|
122
|
+
}
|
|
123
|
+
const startedAt = Date.now();
|
|
124
|
+
try {
|
|
125
|
+
const result = yield _chunkJMRHLOBDcjs.renderApp.call(void 0, app, {
|
|
126
|
+
context: browserContext(req),
|
|
127
|
+
inputs,
|
|
128
|
+
params,
|
|
129
|
+
pathname,
|
|
130
|
+
search
|
|
131
|
+
});
|
|
132
|
+
const elapsed = Date.now() - startedAt;
|
|
133
|
+
if (elapsed >= slowRenderMs) {
|
|
134
|
+
serveLog.warn(`\u043C\u0435\u0434\u043B\u0435\u043D\u043D\u044B\u0439 \u0440\u0435\u043D\u0434\u0435\u0440 \xAB${pathname}\xBB: ${String(elapsed)}\u043C\u0441`);
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
} catch (error) {
|
|
138
|
+
serveLog.error(`\u0440\u0435\u043D\u0434\u0435\u0440 \xAB${pathname}\xBB \u0443\u043F\u0430\u043B \u0437\u0430 ${String(Date.now() - startedAt)}\u043C\u0441`, error);
|
|
139
|
+
return reply.send(error instanceof Error ? error : new Error(String(error)));
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
instance.get("/_render", (req, reply) => handleRender(req, reply, req.query.url, void 0));
|
|
144
|
+
instance.route({
|
|
145
|
+
handler: (req, reply) => {
|
|
146
|
+
var _a2;
|
|
147
|
+
const body = (_a2 = req.body) != null ? _a2 : {};
|
|
148
|
+
return handleRender(req, reply, body.url, body.inputs);
|
|
149
|
+
},
|
|
150
|
+
method: "QUERY",
|
|
151
|
+
url: "/_render"
|
|
152
|
+
});
|
|
146
153
|
return Promise.resolve();
|
|
147
154
|
};
|
|
148
155
|
|
package/serve/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { FastifyInstance, FastifyPluginAsync } from 'fastify';
|
|
2
|
-
import { I as IslandDescriptor } from '../descriptor-
|
|
3
|
-
import { A as AppRoute } from '../routes-
|
|
4
|
-
import '../define-slot-
|
|
5
|
-
import '../types-
|
|
2
|
+
import { I as IslandDescriptor } from '../descriptor-C2j6Zz6c.cjs';
|
|
3
|
+
import { A as AppRoute } from '../routes-BvV405k4.cjs';
|
|
4
|
+
import '../define-slot-BEeHNEph.cjs';
|
|
5
|
+
import '../types-BxMQ-VOd.cjs';
|
|
6
6
|
import '@foxford/ioc';
|
|
7
7
|
|
|
8
8
|
/** Что раздаётся и по какому префиксу. */
|
package/serve/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { FastifyInstance, FastifyPluginAsync } from 'fastify';
|
|
2
|
-
import { I as IslandDescriptor } from '../descriptor-
|
|
3
|
-
import { A as AppRoute } from '../routes-
|
|
4
|
-
import '../define-slot-
|
|
5
|
-
import '../types-
|
|
2
|
+
import { I as IslandDescriptor } from '../descriptor-BSaHM5B4.js';
|
|
3
|
+
import { A as AppRoute } from '../routes-Di3K_0uQ.js';
|
|
4
|
+
import '../define-slot-CdWdFM16.js';
|
|
5
|
+
import '../types-BxMQ-VOd.js';
|
|
6
6
|
import '@foxford/ioc';
|
|
7
7
|
|
|
8
8
|
/** Что раздаётся и по какому префиксу. */
|
package/serve/index.js
CHANGED
|
@@ -4,8 +4,9 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
matchRoute,
|
|
6
6
|
normalizeRoutes,
|
|
7
|
+
parseCookieHeader,
|
|
7
8
|
renderApp
|
|
8
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-VO3ORM7Z.js";
|
|
9
10
|
import "../chunk-E23E2VUC.js";
|
|
10
11
|
import "../chunk-3RX2OSUL.js";
|
|
11
12
|
import {
|
|
@@ -78,20 +79,6 @@ function matchClaim(app, pathname) {
|
|
|
78
79
|
}
|
|
79
80
|
return (_b = (_a = matchRoute(app.routes, pathname)) == null ? void 0 : _a.params) != null ? _b : null;
|
|
80
81
|
}
|
|
81
|
-
function parseCookies(header) {
|
|
82
|
-
const cookies = {};
|
|
83
|
-
for (const part of (header != null ? header : "").split(";")) {
|
|
84
|
-
const eq = part.indexOf("=");
|
|
85
|
-
if (eq < 1) {
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
const name = part.slice(0, eq).trim();
|
|
89
|
-
if (name && !(name in cookies)) {
|
|
90
|
-
cookies[name] = part.slice(eq + 1).trim();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return cookies;
|
|
94
|
-
}
|
|
95
82
|
function browserContext(req) {
|
|
96
83
|
const headers = {};
|
|
97
84
|
const forwarded = {
|
|
@@ -107,7 +94,7 @@ function browserContext(req) {
|
|
|
107
94
|
if (typeof cookie === "string" && cookie !== "") {
|
|
108
95
|
headers.cookie = cookie;
|
|
109
96
|
}
|
|
110
|
-
return { cookies:
|
|
97
|
+
return { cookies: parseCookieHeader(cookie), headers };
|
|
111
98
|
}
|
|
112
99
|
var appPlugin = (instance, options) => {
|
|
113
100
|
var _a, _b;
|
|
@@ -119,30 +106,50 @@ var appPlugin = (instance, options) => {
|
|
|
119
106
|
void reply.header("cache-control", "no-store");
|
|
120
107
|
return claim(app);
|
|
121
108
|
});
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
const { pathname, search } = new URL(target, "http://localhost");
|
|
128
|
-
const params = matchClaim(app, pathname);
|
|
129
|
-
if (params === null) {
|
|
130
|
-
serveLog.error(`\u043F\u0443\u0442\u044C \xAB${pathname}\xBB \u0432\u043D\u0435 \u0437\u0430\u044F\u0432\u043A\u0438 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F`);
|
|
131
|
-
return reply.code(404).send({ error: `\u043F\u0443\u0442\u044C \xAB${pathname}\xBB \u0432\u043D\u0435 \u0437\u0430\u044F\u0432\u043A\u0438 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F` });
|
|
132
|
-
}
|
|
133
|
-
const startedAt = Date.now();
|
|
134
|
-
try {
|
|
135
|
-
const result = yield renderApp(app, { context: browserContext(req), params, pathname, search });
|
|
136
|
-
const elapsed = Date.now() - startedAt;
|
|
137
|
-
if (elapsed >= slowRenderMs) {
|
|
138
|
-
serveLog.warn(`\u043C\u0435\u0434\u043B\u0435\u043D\u043D\u044B\u0439 \u0440\u0435\u043D\u0434\u0435\u0440 \xAB${pathname}\xBB: ${String(elapsed)}\u043C\u0441`);
|
|
109
|
+
function handleRender(req, reply, target, inputs) {
|
|
110
|
+
return __async(this, null, function* () {
|
|
111
|
+
if (typeof target !== "string" || !target.startsWith("/")) {
|
|
112
|
+
return reply.code(400).send({ error: "\u043D\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u043D \u0438\u043B\u0438 \u043D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440 url" });
|
|
139
113
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
114
|
+
if (inputs !== void 0 && (typeof inputs !== "object" || inputs === null || Array.isArray(inputs))) {
|
|
115
|
+
return reply.code(400).send({ error: "inputs \u0434\u043E\u043B\u0436\u043D\u044B \u0431\u044B\u0442\u044C \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u043C \u043F\u043E \u043A\u043B\u044E\u0447\u0443 token.description" });
|
|
116
|
+
}
|
|
117
|
+
const { pathname, search } = new URL(target, "http://localhost");
|
|
118
|
+
const params = matchClaim(app, pathname);
|
|
119
|
+
if (params === null) {
|
|
120
|
+
serveLog.error(`\u043F\u0443\u0442\u044C \xAB${pathname}\xBB \u0432\u043D\u0435 \u0437\u0430\u044F\u0432\u043A\u0438 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F`);
|
|
121
|
+
return reply.code(404).send({ error: `\u043F\u0443\u0442\u044C \xAB${pathname}\xBB \u0432\u043D\u0435 \u0437\u0430\u044F\u0432\u043A\u0438 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F` });
|
|
122
|
+
}
|
|
123
|
+
const startedAt = Date.now();
|
|
124
|
+
try {
|
|
125
|
+
const result = yield renderApp(app, {
|
|
126
|
+
context: browserContext(req),
|
|
127
|
+
inputs,
|
|
128
|
+
params,
|
|
129
|
+
pathname,
|
|
130
|
+
search
|
|
131
|
+
});
|
|
132
|
+
const elapsed = Date.now() - startedAt;
|
|
133
|
+
if (elapsed >= slowRenderMs) {
|
|
134
|
+
serveLog.warn(`\u043C\u0435\u0434\u043B\u0435\u043D\u043D\u044B\u0439 \u0440\u0435\u043D\u0434\u0435\u0440 \xAB${pathname}\xBB: ${String(elapsed)}\u043C\u0441`);
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
} catch (error) {
|
|
138
|
+
serveLog.error(`\u0440\u0435\u043D\u0434\u0435\u0440 \xAB${pathname}\xBB \u0443\u043F\u0430\u043B \u0437\u0430 ${String(Date.now() - startedAt)}\u043C\u0441`, error);
|
|
139
|
+
return reply.send(error instanceof Error ? error : new Error(String(error)));
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
instance.get("/_render", (req, reply) => handleRender(req, reply, req.query.url, void 0));
|
|
144
|
+
instance.route({
|
|
145
|
+
handler: (req, reply) => {
|
|
146
|
+
var _a2;
|
|
147
|
+
const body = (_a2 = req.body) != null ? _a2 : {};
|
|
148
|
+
return handleRender(req, reply, body.url, body.inputs);
|
|
149
|
+
},
|
|
150
|
+
method: "QUERY",
|
|
151
|
+
url: "/_render"
|
|
152
|
+
});
|
|
146
153
|
return Promise.resolve();
|
|
147
154
|
};
|
|
148
155
|
|
|
@@ -774,4 +774,4 @@ declare const ActivatableToken: Token<Activatable>;
|
|
|
774
774
|
*/
|
|
775
775
|
declare const RequestContextToken: Token<RequestContext>;
|
|
776
776
|
|
|
777
|
-
export { type ActionGuard as A, type
|
|
777
|
+
export { type ActionGuard as A, type DefineLayerOptions as B, type Core as C, type DefineRepositoryOptions as D, type ExtensionConfig as E, type Activatable as F, type GuardDefinition as G, ActivatableToken as H, ContainerManagerToken as I, GuardRunnerToken as J, NavigationManagerToken as K, type LayerDefinition as L, StateCache as M, type NavigationManager as N, type StateParticipant as O, StateRegistry as P, StateRegistryToken as Q, type RequestContext as R, type ServiceDefinition as S, StateSerializerToken as T, type ViewModelDefinition as V, type DefineServiceOptions as a, type DefineViewModelOptions as b, type Definition as c, type RepositoryDefinition as d, type SlotEntry as e, SlotRegistry as f, SlotRegistryToken as g, type LayerConfig as h, RequestContextToken as i, type ContainerManager as j, type GuardRunner as k, type Guard as l, type GuardResult as m, type NavigationEntry as n, type NavigationInterceptor as o, type Disposable as p, type LeaveGuardResult as q, type StateSerializer as r, type DefineGuardOptions as s, type DefineExtensionOptions as t, type ExtensionDefinition as u, type DefineActionGuardOptions as v, type ActionGuardDefinition as w, type LayoutConfig as x, type DefineLayoutOptions as y, type LayoutDefinition as z };
|
|
@@ -774,4 +774,4 @@ declare const ActivatableToken: Token<Activatable>;
|
|
|
774
774
|
*/
|
|
775
775
|
declare const RequestContextToken: Token<RequestContext>;
|
|
776
776
|
|
|
777
|
-
export { type ActionGuard as A, type
|
|
777
|
+
export { type ActionGuard as A, type DefineLayerOptions as B, type Core as C, type DefineRepositoryOptions as D, type ExtensionConfig as E, type Activatable as F, type GuardDefinition as G, ActivatableToken as H, ContainerManagerToken as I, GuardRunnerToken as J, NavigationManagerToken as K, type LayerDefinition as L, StateCache as M, type NavigationManager as N, type StateParticipant as O, StateRegistry as P, StateRegistryToken as Q, type RequestContext as R, type ServiceDefinition as S, StateSerializerToken as T, type ViewModelDefinition as V, type DefineServiceOptions as a, type DefineViewModelOptions as b, type Definition as c, type RepositoryDefinition as d, type SlotEntry as e, SlotRegistry as f, SlotRegistryToken as g, type LayerConfig as h, RequestContextToken as i, type ContainerManager as j, type GuardRunner as k, type Guard as l, type GuardResult as m, type NavigationEntry as n, type NavigationInterceptor as o, type Disposable as p, type LeaveGuardResult as q, type StateSerializer as r, type DefineGuardOptions as s, type DefineExtensionOptions as t, type ExtensionDefinition as u, type DefineActionGuardOptions as v, type ActionGuardDefinition as w, type LayoutConfig as x, type DefineLayoutOptions as y, type LayoutDefinition as z };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { I as IslandDescriptor } from './descriptor-
|
|
1
|
+
import { I as IslandDescriptor } from './descriptor-C2j6Zz6c.cjs';
|
|
2
2
|
import { S as ServerRenderResult } from './server-render-CocWXQKC.cjs';
|
|
3
|
-
import { L as LayerDefinition, h as LayerConfig } from './types-
|
|
3
|
+
import { L as LayerDefinition, h as LayerConfig } from './types-BxMQ-VOd.cjs';
|
|
4
4
|
import { Container, Token } from '@foxford/ioc';
|
|
5
5
|
|
|
6
6
|
/** Что нужно адаптеру, чтобы отрисовать остров на сервере. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { I as IslandDescriptor } from './descriptor-
|
|
1
|
+
import { I as IslandDescriptor } from './descriptor-BSaHM5B4.js';
|
|
2
2
|
import { S as ServerRenderResult } from './server-render-CocWXQKC.js';
|
|
3
|
-
import { L as LayerDefinition, h as LayerConfig } from './types-
|
|
3
|
+
import { L as LayerDefinition, h as LayerConfig } from './types-BxMQ-VOd.js';
|
|
4
4
|
import { Container, Token } from '@foxford/ioc';
|
|
5
5
|
|
|
6
6
|
/** Что нужно адаптеру, чтобы отрисовать остров на сервере. */
|