@opetope/runtime 0.1.1 → 0.2.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/CHANGELOG.md +20 -0
- package/README.md +19 -9
- package/README.ru.md +21 -9
- package/dist/feature-authoring-types.d.ts +6 -10
- package/dist/feature-authoring.js +1 -1
- package/dist/feature-authoring.js.map +1 -1
- package/dist/feature-body.d.ts +1 -1
- package/dist/feature-body.js.map +1 -1
- package/dist/feature-contribution.d.ts +5 -3
- package/dist/feature-contribution.js +1 -1
- package/dist/feature-contribution.js.map +1 -1
- package/dist/feature-definition-api.d.ts +1 -1
- package/dist/feature-generation.js +1 -1
- package/dist/feature-generation.js.map +1 -1
- package/dist/feature-lazy-generation.d.ts +1 -1
- package/dist/feature-lazy-generation.js +1 -1
- package/dist/feature-lazy-generation.js.map +1 -1
- package/dist/feature-own-values.d.ts +10 -0
- package/dist/feature-own-values.js +2 -0
- package/dist/feature-own-values.js.map +1 -0
- package/dist/feature-port-binding.d.ts +2 -1
- package/dist/feature-port-binding.js +1 -1
- package/dist/feature-port-binding.js.map +1 -1
- package/dist/feature-port.d.ts +13 -23
- package/dist/feature-port.js +1 -1
- package/dist/feature-port.js.map +1 -1
- package/dist/public-module-types.d.ts +1 -1
- package/dist/public-module.d.ts +1 -1
- package/docs/agent-guide.md +11 -4
- package/docs/agent-guide.ru.md +11 -4
- package/docs/cookbook.md +9 -7
- package/docs/cookbook.ru.md +9 -7
- package/docs/decisions.md +14 -0
- package/docs/how-it-works.md +20 -5
- package/docs/how-it-works.ru.md +19 -5
- package/docs/spec.md +31 -17
- package/docs/spec.ru.md +32 -18
- package/package.json +3 -3
package/docs/spec.ru.md
CHANGED
|
@@ -55,8 +55,8 @@ const catalogCatalogFeature = defineFeature({
|
|
|
55
55
|
...calls(imports.platform, ['resolveItem']), // методы хоста как Call, один к одному
|
|
56
56
|
}),
|
|
57
57
|
exports: ({ own }) => ({ resolveItem: own.resolveItem }), // для фич, импортирующих это определение
|
|
58
|
-
provides: ({ port
|
|
59
|
-
resolve: port(resolveItemPort, own.resolveItem), // порт для тех, кто его требует
|
|
58
|
+
provides: ({ port }) => ({
|
|
59
|
+
resolve: port(resolveItemPort, ({ own }) => own.resolveItem), // порт для тех, кто его требует
|
|
60
60
|
}),
|
|
61
61
|
});
|
|
62
62
|
```
|
|
@@ -103,17 +103,18 @@ const createFormFeature = defineFeature({
|
|
|
103
103
|
order: model(OrderModel, { platform: imports.platform }, (ctx, { platform }) => createOrderModel(ctx, platform)),
|
|
104
104
|
lookup: requires.resolveItem, // в `own` порт остаётся ref-ом
|
|
105
105
|
}),
|
|
106
|
-
//
|
|
107
|
-
exports: ({ own }) => ({ lookup: own.lookup
|
|
106
|
+
// потребители получают публичный Call lookup; submit остаётся внутри этой фичи
|
|
107
|
+
exports: ({ own }) => ({ lookup: own.lookup }),
|
|
108
108
|
provides: ({ slot, pipe }) => ({
|
|
109
109
|
// вклад это значение, фабрика экземпляра или дескриптор pipe; `priority` и `when` в опциях третьим
|
|
110
|
-
content: slot(orderFormContentSlot, ({
|
|
110
|
+
content: slot(orderFormContentSlot, ({ own, model }) => ({
|
|
111
111
|
Component: CreateForm,
|
|
112
112
|
// UI-модель вклада: создаётся на каждое монтирование и видит `props` именно этого монтирования
|
|
113
113
|
models: [
|
|
114
114
|
model(OrderActions, (ctx, props: Readable<OrderFormProps>) => ({
|
|
115
115
|
submit: ctx.call({
|
|
116
|
-
run: (amount: number, { invoke }) =>
|
|
116
|
+
run: (amount: number, { invoke }) =>
|
|
117
|
+
invoke(own.order.submit, { amount, itemId: props.getSnapshot().itemId }),
|
|
117
118
|
}),
|
|
118
119
|
})),
|
|
119
120
|
],
|
|
@@ -179,7 +180,7 @@ publication barrier. Всё это принадлежит runtime и его inte
|
|
|
179
180
|
| `id` | Как фича называется | `'feature.entity'`, только точки, без суффиксов |
|
|
180
181
|
| `imports` | Что мне дадут снаружи | запись из `defineHostContract` контрактов и определений других фич; `optional(x)` это слабое ребро, `onDemand(hostContract)` откладывает подключение до первого вызова |
|
|
181
182
|
| `requires` | Какой порт мне нужен | запись `port` или `optional(port)`; каждое `requires.x` это ref, а `Call` появляется у экземпляра |
|
|
182
|
-
| ref vs Call | Что видно в какой стадии | `own`
|
|
183
|
+
| ref vs Call | Что видно в какой стадии | builder `own` видит refs зависимостей; `provides` видит только builders; `exports`, селекторы портов и фабрики вкладов видят готовые значения экземпляра |
|
|
183
184
|
| `own` | Чем я владею | builder: `model`, `call`, `calls`, `lane`, `effect`, `event`, `resource`, `stream`, `scope`, `attach` |
|
|
184
185
|
| `exports` | Что я отдаю фичам, которые меня импортируют | `({ own }) => запись Call, Readable и Resource` на открытии экземпляра |
|
|
185
186
|
| `provides` | Что я предлагаю точкам расширения | `({ port, slot, pipe, register, own }) => ...` |
|
|
@@ -267,13 +268,17 @@ input, а не автоматически переданным токеном о
|
|
|
267
268
|
используется та же запись, без зависимостей — `model(Decl, create)`. Принимаются только подлинные импорты и call
|
|
268
269
|
refs текущей фичи; optional-импорты сохраняют `Readable<Lookup<…>>`. Сырые объекты хоста, декларации портов,
|
|
269
270
|
чужие refs и refs моделей не являются элементами зависимостей. Именованная фабрика может объявить свой интерфейс
|
|
270
|
-
зависимостей, не видя контекста фичи. `
|
|
271
|
-
|
|
272
|
-
переданные напрямую вызовы.
|
|
271
|
+
зависимостей, не видя контекста фичи. `port(SubmitPort, ({ own }) => own.order.submit)` один раз выбирает подлинный
|
|
272
|
+
вызов из `own` текущего экземпляра при подготовке, до readiness и публикации вкладов, и добавляет фенс провайдера,
|
|
273
|
+
включая переданные напрямую вызовы. `port(SubmitPort, ({ own }) => own.submit)` выбирает вызов, объявленный прямо
|
|
274
|
+
в `own`. Селектор получает только `{ own }`; результатом должен быть подлинный Call из значения, выбранного им
|
|
275
|
+
в этом `own`, в том числе из поля модели. Чужие Calls и обычные функции отвергаются. Прямые refs и дескрипторы
|
|
276
|
+
`{ from, select }` не принимаются. Retirement внутри селектора прекращает запуск следующих селекторов и дренирует
|
|
277
|
+
уже владеемую работу (D255).
|
|
273
278
|
|
|
274
279
|
Моделей у вклада два вида, и обе объявлены одним `defineModel`. Модели `own` живут с экземпляром фичи и служатся
|
|
275
280
|
монтированию автоматически. UI-модель вклада живёт с монтированием: она перечислена в `models` вклада, её фабрика
|
|
276
|
-
получает вторым аргументом `Readable` пропсов этого монтирования и берёт поля как есть (`submit:
|
|
281
|
+
получает вторым аргументом `Readable` пропсов этого монтирования и берёт поля как есть (`submit: own.order.submit`)
|
|
277
282
|
или оборачивает их в `ctx.call`, когда контракт UI отличается входом, формой результата или числом фичевых вызовов.
|
|
278
283
|
Отдельного понятия View нет.
|
|
279
284
|
|
|
@@ -437,17 +442,26 @@ scope: отдельный концепт, а не второе имя фичи.
|
|
|
437
442
|
`event`, `resource`, `stream`, `scope.while`, `scope.switch`, `scope.keyed`, `attach`. У `resource`,
|
|
438
443
|
`stream` и `event` источник и носитель вывода типа позиционные: `resource(from, target, {…})`,
|
|
439
444
|
`stream(from, target, {…})`, `event(from, subscribe, {…})`; порядок ключей в объекте опций свободен. Одна опция
|
|
440
|
-
несёт для обоих одно слово: `stream` требует `backpressure: latest()`, а `event` его допускает.
|
|
441
|
-
`port
|
|
445
|
+
несёт для обоих одно слово: `stream` требует `backpressure: latest()`, а `event` его допускает. Внешняя фабрика
|
|
446
|
+
`provides` получает ровно `{ port, slot, pipe, register }`: только builders, без `own` и других значений экземпляра.
|
|
447
|
+
`port(Port, ({ own }) => own.model.call)` записывает цель при объявлении, а Call выбирает при подготовке экземпляра.
|
|
448
|
+
У вкладов цель первым аргументом, значение или фабрика экземпляра вторым, опции
|
|
442
449
|
третьим: `slot(target, contribution, { priority, when })`, `pipe(target, { fold }, { priority, when })`,
|
|
443
450
|
`register(target, entry, { priority, when })`, причём у `pipe` второй аргумент это дескриптор, потому что голую
|
|
444
|
-
функцию было бы не отличить от фабрики экземпляра.
|
|
445
|
-
`model(Decl, create)` строит UI-модель
|
|
446
|
-
`
|
|
451
|
+
функцию было бы не отличить от фабрики экземпляра. Фабрика `register` получает `{ own, imports }`, а фабрика
|
|
452
|
+
`slot` — `{ own, imports, model }`, где `model(Decl, create)` строит UI-модель монтирования и `create` получает
|
|
453
|
+
`(ctx, props)`. Контексты содержат только перечисленные поля: `exports` и `instance` отсутствуют, а у `register`
|
|
454
|
+
нет построителя моделей (D255). В обеих вложенных фабриках `own` содержит материализованные модели, вызовы и
|
|
455
|
+
ресурсы этого экземпляра, как в `exports`. `register(target, ({ own }) => ({ key: 'submit', value: own.order.submit }))`
|
|
456
|
+
публикует вызов внутренней модели без секции `exports`. Селекторы портов и фабрики вкладов выбирают готовые
|
|
457
|
+
значения через собственный контекст колбэка. У вложений, scopes,
|
|
458
|
+
effects и events нет доступной для чтения формы значения; невыбранные поля не мешают обращаться к соседней
|
|
459
|
+
модели или вызову. `when` это
|
|
460
|
+
`Readable<boolean>` или предикат экземпляра — `({ own, imports, read }) => boolean`, — чей `read`
|
|
447
461
|
записывает, от чего зависит ответ: пока ответ `false`, вклад не входит в `entries` цели. В этом контексте
|
|
448
462
|
вычисления `own` дан в материализованной форме, которую видит `exports`: поле модели это `Readable`, а не ref из
|
|
449
|
-
|
|
450
|
-
`(value, meta, {
|
|
463
|
+
builder `own`. `fold` дескриптора `pipe` получает третьим аргументом тот же контекст вычисления —
|
|
464
|
+
`(value, meta, { own, imports, read }) => …`, — связанный с экземпляром один раз при публикации вклада и
|
|
451
465
|
вызываемый только сверткой, а не при объявлении или предзагрузке; а `target.fold(value, meta, read?)` принимает
|
|
452
466
|
читателя третьим параметром, поэтому `computed({ read: read => target.fold(0, undefined, read) })` подписывается и
|
|
453
467
|
на `entries`, и на всё, что прочитали обработчики; без читателя обработчики читают текущий snapshot. Контексты:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opetope/runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=20.19.0"
|
|
6
6
|
},
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
}
|
|
53
53
|
],
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@opetope/core": "0.
|
|
55
|
+
"@opetope/core": "0.2.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@opetope/core": "0.
|
|
58
|
+
"@opetope/core": "0.2.0"
|
|
59
59
|
},
|
|
60
60
|
"sideEffects": false,
|
|
61
61
|
"description": "Feature composition and owned lifecycles for Opetope.",
|