diff --git a/.changeset/a-page-returns-to-its-index.md b/.changeset/a-page-returns-to-its-index.md deleted file mode 100644 index 3e7321f..0000000 --- a/.changeset/a-page-returns-to-its-index.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -'@bedrock-core/guides': minor ---- - -A guide opens on its home page, and every page is one press from the index. - -`guide_home` is where a guide opens: the page marked `home: true`, the only page of a single-page -guide, or the index when there is neither. `guide_home_back` is the same entry with a back control, -what a host that opened the guide shows in its place. `guide_index` is the index itself, compiled -once, and exported as `guideIndexScreen`. - -Moving inside a guide replaces rather than stacks. A page's back and its index button both open -`guide_index` in the page's place, and a row of the index opens its page in the index's place. In a -guide with a home page the index's back opens `guide_home_back` in its place, and the home page's -own back leads to wherever the guide was opened from; in a guide with none, the index's back does. -A reader who followed six links is one press from the index. A single-page guide has no index -button, and its back leaves the guide. - -The screen names live in their own module, exported from the package root. The half that BUILDS -the screens and the half that FINDS them in another addon's pack must agree exactly, since a key is -`:` and the two never meet at runtime. diff --git a/.changeset/apps-are-three-peers.md b/.changeset/apps-are-three-peers.md deleted file mode 100644 index 2284878..0000000 --- a/.changeset/apps-are-three-peers.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -'@bedrock-core/config': minor -'@bedrock-core/guides': minor ---- - -**Breaking.** The UI is three peer apps, and each one is a field of `core.register()`. - -`@bedrock-core/config` was the addon list, the config screens and the guide viewer in one mount. -Those are three different things to want, so they are three packages: `@bedrock-core/catalog` -browses every addon in the world, `@bedrock-core/config` holds an addon's settings and the screens -that edit them, and `@bedrock-core/guides` shows its guide. Each installs on its own. - -```ts -// before -import { ui } from '@bedrock-core/config'; -import { config } from '@bedrock-core/config/server'; - -core.register({ manifest, config: config(definition) }); -ui(core); // the list, the config screens, the guide, and four commands - -// after -import { registerCatalog } from '@bedrock-core/catalog'; -import { registerConfig } from '@bedrock-core/config'; -import { registerGuides } from '@bedrock-core/guides/server'; - -const { config } = core.register({ - manifest, - catalog: registerCatalog(), - config: registerConfig(definition), - guides: registerGuides(), -}); -``` - -`register()` is the whole mount — there is no second call, and taking two of the three is dropping -a field rather than passing a flag. Each declaration installs its own command, serves its own -`core:.show` method and announces that this addon offers that app, so what a realm can do for -a player follows from what the addon asked for. - -A declaration takes only what the build cannot work out for itself. `registerConfig(definition)` -takes the definition because the definition *is* the declaration: the runtime installs the scopes -from it and the ui-compiler filter reads it out of that very call to shape one screen per section. -`registerCatalog()` and `registerGuides()` take nothing at all — the roster is `core.registry`, and -the guide's pages are already compiled into the pack — so their presence is the entire statement. -Each also takes `{ commands: false }`, which frees the command name without unmounting the app. - -Each app owns one command, under the addon's own namespace: `:config` and `:configat` stay -here, `:catalog` belongs to the catalog (`:list` is gone — vanilla owns `/list`, and the -alias Bedrock grants the first registrant cannot be claimed for a name it already has), and -`:guide` belongs to the guide app. - -Removed from `@bedrock-core/config`, with where each went: - -- `ui`, `openUi` and `UiOptions` — `registerConfig()` mounts, and `config.open(player, target?)` on - the returned accessor is the funnel that `openUi` was. The permission clamp is still behind it. -- `addonPageScreen` and `AddonPageInfo` — the page is `AddonPage` and `AddonPageInfo` on - `@bedrock-core/catalog/compiled`; the addon list, the framework's own row and the page geometry - are internal to the catalog. -- `guideAudienceFor` — removed. -- `registerDeclared` and `DeclaredParts` — `@bedrock-core/navigation`. -- `registerAddonCommands`, `OpenCallback`, `allowedScopes`, `clampTarget`, `isOperator`, - `CONFIG_SCOPES`, `ConfigScope`, `EntrySchema` and `FlatSchemaLike` — internal. - `registerConfig(definition, { commands: false })` with `config.open(player, target?)` makes your - own entry point, and `isOperator` is `@bedrock-core/server`'s. - -`@bedrock-core/config/server` renames its field factory `config` to `registerConfig`, matching the -name the root exports: the two are the same field, one with screens and one without, and an addon -that draws nothing imports the subpath alone. The subsystem reaches the runtime through a -namespaced slot rather than a fixed property — `configOf(core)` reads what the declaration filled -under `core:config`. - -`@bedrock-core/guides` gains `@bedrock-core/guides/server`, the guide app's server half: -`registerGuides`, `guidesOf` and their types. It runs on a bare `Runtime` and draws nothing. The -package root re-exports it beside the screen factories the guides filter's generated modules call, -`openGuide` and `GuideComponents`. `GuideBlockList`, `resolveLanding`, `canSee`, -`hasVisiblePages`, `paginationFor`, `visiblePageIds`, `visibleTree`, `isGuideManifest`, -`guideScreenName` and the manifest types are internal: a guide renders from what the filter -compiles. diff --git a/.changeset/compiled-screens-only.md b/.changeset/compiled-screens-only.md deleted file mode 100644 index 0ae7cca..0000000 --- a/.changeset/compiled-screens-only.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@bedrock-core/config': minor ---- - -**Breaking.** Every screen the config UI draws is compiled into the pack. `App`, `AppProps`, `AppRoutes` and `AppScreen` are removed from `@bedrock-core/config`. diff --git a/.changeset/drawn-by-the-pack-that-holds-it.md b/.changeset/drawn-by-the-pack-that-holds-it.md deleted file mode 100644 index 8e7fa86..0000000 --- a/.changeset/drawn-by-the-pack-that-holds-it.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -'@bedrock-core/config': minor ---- - -**Breaking.** A screen is drawn by the addon whose pack holds it, and a crossing carries the way -back. - -A config target naming another addon is handed to that addon's realm before anything is drawn: -the screens read and write the addon's own scopes, so its settings, its page and its guide are -served by it. No realm draws another addon's settings. - -Config is local. `configOf(core).of()`, `configOf(core).subscribe()`, `RemoteConfigAccessor`, -`TypedRemoteConfig`, `ConfigAccessOptions`, the nine `core:config..` RPC -methods and the `core-config/schema` and `core-config/groups` announcements are gone, and -`configOf(core).local` gains `groups`. An addon that wants its settings read or written from -another realm serves them over its own RPC. - -One method does all of it, `core:ui.show(playerId, target, returnTo?)`, and the third argument is -what makes a crossing survivable. A return address names a PLACE rather than a screen key — a -list, a menu level and a roster are each drawn from a model, and rendering their component with no -model draws the empty shape of the screen. Each hop carries the whole way back in the request, so -a chain of any depth walks home through the realms it came through rather than dead-ending on the -far side. - -A row whose realm does not answer is still drawn here, from the page reference that addon -published, exactly as before. Handing off is what happens when the owner is present, not a -requirement for appearing at all. - -The open target is now one per app rather than one shared union, and internal to it. -`isOpenTarget`, `OpenTarget` and `OpenCommand` are gone — a target crosses a realm as plain -data, and each app reads its own. A realm running an older copy understands as much of a target as -it knows and falls back for the rest. - -The permission clamp applies on arrival rather than at the entry points. A target also arrives -from the wire, where no caller in this realm has applied it, so a non-operator cannot reach past -their own player scope even when the request says otherwise. diff --git a/.changeset/guide-paragraph-is-one-text.md b/.changeset/guide-paragraph-is-one-text.md deleted file mode 100644 index 9e11000..0000000 --- a/.changeset/guide-paragraph-is-one-text.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@bedrock-core/guides': minor ---- - -**Breaking.** A paragraph or list item with links is drawn with `Trans`: the build breaks it into the same number of lines in every language, and each link is pressable only where its own text is drawn, in whichever language the client shows. The manifest's `GuideRun` is gone. An inline block carries `k` when it has no links, and when it has, `text` — a tagged string by locale, `See <0>the page.` — and `links`, the page each numbered tag opens, matching the guides filter that writes it. diff --git a/.changeset/guides-operator-pages.md b/.changeset/guides-operator-pages.md deleted file mode 100644 index 4f679a2..0000000 --- a/.changeset/guides-operator-pages.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -'@bedrock-core/guides': minor ---- - -A page or category marked `access: op` is shown to world operators only. - -A guide with anything gated is compiled once per audience. `guide_home`, `guide_home_back`, -`guide_index` and `guide_` are what every player is shown: a gated page has no screen there, -the index lists only what a player may open, prev and next skip what they may not, a gated home -page is no home to them, and a link to a gated page, in a paragraph, a list, an admonition or a -component's children, is drawn as text. `guideop_home`, `guideop_home_back`, `guideop_index` and -`guideop_` are the operators' set: every page, and every press inside it leads within it. A -guide with nothing gated compiles the ordinary set alone. - -The entry decides which set a reader walks. `guides.open(player, addonId?)`, the `:guide` -command, a catalog's guide button and `openGuide(ns, player)` open an operator on the operators' -set when the guide has one, and everyone else on the ordinary set. A `` to `guide_home` or -`guide_home_back` is the same press for every viewer, so it always opens the ordinary set. -`openGuide(ns, player, { back: true })` opens the entry with a back control, in the set the player -reads, for a screen that links to a guide. - -The screen factories take `audience: 'op'` for the operators' set, which is what the guides filter -writes, and the manifest carries `opScreens`, each page's screen name in that set. diff --git a/.changeset/navigate-by-key.md b/.changeset/navigate-by-key.md deleted file mode 100644 index a2a656f..0000000 --- a/.changeset/navigate-by-key.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@bedrock-core/guides': minor ---- - -**Breaking.** A guide is its compiled screens, navigated by key. - -`createGuide` is removed: a page is a screen rather than a state of one. `guideReference`, `presentGuideReference`, `isGuideReference` and `GuideReference` go with it, because a guide's screens ride the ordinary screen table. `openGuide(ns, player)` is a `navigate()`, so it opens this bundle's guide or another addon's the same way. The views take link keys (`linkTo`, `homeTo`) instead of open-page callbacks. diff --git a/.changeset/screens-from-the-declaration.md b/.changeset/screens-from-the-declaration.md deleted file mode 100644 index 44ed36b..0000000 --- a/.changeset/screens-from-the-declaration.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@bedrock-core/config': minor ---- - -An addon's screens follow from what it declared. - -`core.register()` is read at build time, and what follows from it is compiled: one config screen per section of the declared schema — shaped for the settings that section has, each drawn as the control it is, with its label baked — and the addon's page in the shared list, drawn from its manifest. A list's items get a screen of their own, with the options a present offers filled in rather than baked. - -There is no cap on rows or options, because a screen serving any schema is the only thing that needed one. diff --git a/.changeset/select-and-multiselect.md b/.changeset/select-and-multiselect.md deleted file mode 100644 index 9546cf8..0000000 --- a/.changeset/select-and-multiselect.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@bedrock-core/config': minor ---- - -**Breaking.** The `enum` entry type is `select`, and `EnumEntry` is `SelectEntry`. A `list` is free -strings only: `itemType` and `options` are gone from it, and a setting drawn from a fixed set is a -`multiselect`. - -A `select` and a `multiselect` take `options` as a string array or a string `enum`, and both infer -from them: a select reads back as one of its options, and a multiselect as an array of them where -it read back as `string[]`. `EntryOptions` and `OptionValue` are exported beside the entry types. diff --git a/.changeset/settings-rows-in-the-vanilla-shape.md b/.changeset/settings-rows-in-the-vanilla-shape.md deleted file mode 100644 index 4628135..0000000 --- a/.changeset/settings-rows-in-the-vanilla-shape.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -'@bedrock-core/config': minor ---- - -A setting is drawn as the control it is, showing what is actually stored. - -A shaped leaf reads the scope's stored document rather than the schema's defaults. Values are -nested the way the schema is while a field is named by its flat path, so each one is read down its -path and falls back to what the schema declares only where nothing is set. A section deep-linked -from a command fetches before its first render, so it opens on the values in the world instead of -on defaults it then has to correct. - -Each row takes the shape vanilla gives that control, inside full-width dividers: - -- a toggle sits beside its caption and note; -- a slider sits under its caption and note, with the value at the caption's end; -- every other control takes the note after it. - -A short enum is a segmented control and a longer one stays a dropdown. A multiselect draws a -checkbox per option, answering under `#`, and the host folds those back into the array — -clearing the last box yields an empty array rather than dropping the setting. Save writes and then -goes back; dismissing goes back without writing. A list returns to the section holding it rather -than to the scope root, and the list editor re-presents with its patch merged down the setting's -own path. - -Screen bodies share one rect inside the card's border, so the insets read equal from one screen to -the next, and an addon page keeps a narrower right inset beside the scroll gutter. diff --git a/.changeset/static-screens.md b/.changeset/static-screens.md deleted file mode 100644 index d29208a..0000000 --- a/.changeset/static-screens.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@bedrock-core/guides': minor -'@bedrock-core/config': minor ---- - -A guide page ships as a table, not as a component. - -A guide page is a static screen: every string it shows is baked and every press it takes is a ``. `GuideBlockList`, `GuidePageView`, `GuideHomeView` and the guide manifest are absent from a built addon, and opening a page is one form call. `openGuide(ns, player)` no longer takes the manifest: it navigates to the guide's key, and the manifest is build input that never reaches the addon. A `cmp` block in a guide may not take a press: somewhere to go is a ``, anything else is decoration. diff --git a/packages/config/CHANGELOG.md b/packages/config/CHANGELOG.md index a04350f..14b778c 100644 --- a/packages/config/CHANGELOG.md +++ b/packages/config/CHANGELOG.md @@ -1,5 +1,159 @@ # @bedrock-core/config +## 0.3.0 + +### Minor Changes + +- [`e69758e`](https://github.com/bedrock-core/apps/commit/e69758e3bf6a58755145d0a357eb657a7497eaf9) Thanks [@drav0011](https://github.com/drav0011)! - **Breaking.** The UI is three peer apps, and each one is a field of `core.register()`. + + `@bedrock-core/config` was the addon list, the config screens and the guide viewer in one mount. + Those are three different things to want, so they are three packages: `@bedrock-core/catalog` + browses every addon in the world, `@bedrock-core/config` holds an addon's settings and the screens + that edit them, and `@bedrock-core/guides` shows its guide. Each installs on its own. + + ```ts + // before + import { ui } from '@bedrock-core/config'; + import { config } from '@bedrock-core/config/server'; + + core.register({ manifest, config: config(definition) }); + ui(core); // the list, the config screens, the guide, and four commands + + // after + import { registerCatalog } from '@bedrock-core/catalog'; + import { registerConfig } from '@bedrock-core/config'; + import { registerGuides } from '@bedrock-core/guides/server'; + + const { config } = core.register({ + manifest, + catalog: registerCatalog(), + config: registerConfig(definition), + guides: registerGuides(), + }); + ``` + + `register()` is the whole mount — there is no second call, and taking two of the three is dropping + a field rather than passing a flag. Each declaration installs its own command, serves its own + `core:.show` method and announces that this addon offers that app, so what a realm can do for + a player follows from what the addon asked for. + + A declaration takes only what the build cannot work out for itself. `registerConfig(definition)` + takes the definition because the definition *is* the declaration: the runtime installs the scopes + from it and the ui-compiler filter reads it out of that very call to shape one screen per section. + `registerCatalog()` and `registerGuides()` take nothing at all — the roster is `core.registry`, and + the guide's pages are already compiled into the pack — so their presence is the entire statement. + Each also takes `{ commands: false }`, which frees the command name without unmounting the app. + + Each app owns one command, under the addon's own namespace: `:config` and `:configat` stay + here, `:catalog` belongs to the catalog (`:list` is gone — vanilla owns `/list`, and the + alias Bedrock grants the first registrant cannot be claimed for a name it already has), and + `:guide` belongs to the guide app. + + Removed from `@bedrock-core/config`, with where each went: + + - `ui`, `openUi` and `UiOptions` — `registerConfig()` mounts, and `config.open(player, target?)` on + the returned accessor is the funnel that `openUi` was. The permission clamp is still behind it. + - `addonPageScreen` and `AddonPageInfo` — the page is `AddonPage` and `AddonPageInfo` on + `@bedrock-core/catalog/compiled`; the addon list, the framework's own row and the page geometry + are internal to the catalog. + - `guideAudienceFor` — removed. + - `registerDeclared` and `DeclaredParts` — `@bedrock-core/navigation`. + - `registerAddonCommands`, `OpenCallback`, `allowedScopes`, `clampTarget`, `isOperator`, + `CONFIG_SCOPES`, `ConfigScope`, `EntrySchema` and `FlatSchemaLike` — internal. + `registerConfig(definition, { commands: false })` with `config.open(player, target?)` makes your + own entry point, and `isOperator` is `@bedrock-core/server`'s. + + `@bedrock-core/config/server` renames its field factory `config` to `registerConfig`, matching the + name the root exports: the two are the same field, one with screens and one without, and an addon + that draws nothing imports the subpath alone. The subsystem reaches the runtime through a + namespaced slot rather than a fixed property — `configOf(core)` reads what the declaration filled + under `core:config`. + + `@bedrock-core/guides` gains `@bedrock-core/guides/server`, the guide app's server half: + `registerGuides`, `guidesOf` and their types. It runs on a bare `Runtime` and draws nothing. The + package root re-exports it beside the screen factories the guides filter's generated modules call, + `openGuide` and `GuideComponents`. `GuideBlockList`, `resolveLanding`, `canSee`, + `hasVisiblePages`, `paginationFor`, `visiblePageIds`, `visibleTree`, `isGuideManifest`, + `guideScreenName` and the manifest types are internal: a guide renders from what the filter + compiles. + +- [`ea00fe0`](https://github.com/bedrock-core/apps/commit/ea00fe0a8c94ef9e55c508375f0062293876f954) Thanks [@drav0011](https://github.com/drav0011)! - **Breaking.** Every screen the config UI draws is compiled into the pack. `App`, `AppProps`, `AppRoutes` and `AppScreen` are removed from `@bedrock-core/config`. + +- [`e69758e`](https://github.com/bedrock-core/apps/commit/e69758e3bf6a58755145d0a357eb657a7497eaf9) Thanks [@drav0011](https://github.com/drav0011)! - **Breaking.** A screen is drawn by the addon whose pack holds it, and a crossing carries the way + back. + + A config target naming another addon is handed to that addon's realm before anything is drawn: + the screens read and write the addon's own scopes, so its settings, its page and its guide are + served by it. No realm draws another addon's settings. + + Config is local. `configOf(core).of()`, `configOf(core).subscribe()`, `RemoteConfigAccessor`, + `TypedRemoteConfig`, `ConfigAccessOptions`, the nine `core:config..` RPC + methods and the `core-config/schema` and `core-config/groups` announcements are gone, and + `configOf(core).local` gains `groups`. An addon that wants its settings read or written from + another realm serves them over its own RPC. + + One method does all of it, `core:ui.show(playerId, target, returnTo?)`, and the third argument is + what makes a crossing survivable. A return address names a PLACE rather than a screen key — a + list, a menu level and a roster are each drawn from a model, and rendering their component with no + model draws the empty shape of the screen. Each hop carries the whole way back in the request, so + a chain of any depth walks home through the realms it came through rather than dead-ending on the + far side. + + A row whose realm does not answer is still drawn here, from the page reference that addon + published, exactly as before. Handing off is what happens when the owner is present, not a + requirement for appearing at all. + + The open target is now one per app rather than one shared union, and internal to it. + `isOpenTarget`, `OpenTarget` and `OpenCommand` are gone — a target crosses a realm as plain + data, and each app reads its own. A realm running an older copy understands as much of a target as + it knows and falls back for the rest. + + The permission clamp applies on arrival rather than at the entry points. A target also arrives + from the wire, where no caller in this realm has applied it, so a non-operator cannot reach past + their own player scope even when the request says otherwise. + +- [`ea00fe0`](https://github.com/bedrock-core/apps/commit/ea00fe0a8c94ef9e55c508375f0062293876f954) Thanks [@drav0011](https://github.com/drav0011)! - An addon's screens follow from what it declared. + + `core.register()` is read at build time, and what follows from it is compiled: one config screen per section of the declared schema — shaped for the settings that section has, each drawn as the control it is, with its label baked — and the addon's page in the shared list, drawn from its manifest. A list's items get a screen of their own, with the options a present offers filled in rather than baked. + + There is no cap on rows or options, because a screen serving any schema is the only thing that needed one. + +- [`514e866`](https://github.com/bedrock-core/apps/commit/514e8662f6881a6ddf6e3a919b88dd664ba9316f) Thanks [@drav0011](https://github.com/drav0011)! - **Breaking.** The `enum` entry type is `select`, and `EnumEntry` is `SelectEntry`. A `list` is free + strings only: `itemType` and `options` are gone from it, and a setting drawn from a fixed set is a + `multiselect`. + + A `select` and a `multiselect` take `options` as a string array or a string `enum`, and both infer + from them: a select reads back as one of its options, and a multiselect as an array of them where + it read back as `string[]`. `EntryOptions` and `OptionValue` are exported beside the entry types. + +- [`e69758e`](https://github.com/bedrock-core/apps/commit/e69758e3bf6a58755145d0a357eb657a7497eaf9) Thanks [@drav0011](https://github.com/drav0011)! - A setting is drawn as the control it is, showing what is actually stored. + + A shaped leaf reads the scope's stored document rather than the schema's defaults. Values are + nested the way the schema is while a field is named by its flat path, so each one is read down its + path and falls back to what the schema declares only where nothing is set. A section deep-linked + from a command fetches before its first render, so it opens on the values in the world instead of + on defaults it then has to correct. + + Each row takes the shape vanilla gives that control, inside full-width dividers: + + - a toggle sits beside its caption and note; + - a slider sits under its caption and note, with the value at the caption's end; + - every other control takes the note after it. + + A short enum is a segmented control and a longer one stays a dropdown. A multiselect draws a + checkbox per option, answering under `#`, and the host folds those back into the array — + clearing the last box yields an empty array rather than dropping the setting. Save writes and then + goes back; dismissing goes back without writing. A list returns to the section holding it rather + than to the scope root, and the list editor re-presents with its patch merged down the setting's + own path. + + Screen bodies share one rect inside the card's border, so the insets read equal from one screen to + the next, and an addon page keeps a narrower right inset beside the scroll gutter. + +- [`ea00fe0`](https://github.com/bedrock-core/apps/commit/ea00fe0a8c94ef9e55c508375f0062293876f954) Thanks [@drav0011](https://github.com/drav0011)! - A guide page ships as a table, not as a component. + + A guide page is a static screen: every string it shows is baked and every press it takes is a ``. `GuideBlockList`, `GuidePageView`, `GuideHomeView` and the guide manifest are absent from a built addon, and opening a page is one form call. `openGuide(ns, player)` no longer takes the manifest: it navigates to the guide's key, and the manifest is build input that never reaches the addon. A `cmp` block in a guide may not take a press: somewhere to go is a ``, anything else is decoration. + ## 0.2.0 ### Minor Changes diff --git a/packages/config/package.json b/packages/config/package.json index 79c94fa..133107b 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,6 +1,6 @@ { "name": "@bedrock-core/config", - "version": "0.2.0", + "version": "0.3.0", "description": "The bedrock-core addon list + config + guide UI: one realm serves it for every registered addon", "keywords": [ "minecraft", diff --git a/packages/guides/CHANGELOG.md b/packages/guides/CHANGELOG.md index 9ba4718..04e03d4 100644 --- a/packages/guides/CHANGELOG.md +++ b/packages/guides/CHANGELOG.md @@ -1,5 +1,130 @@ # @bedrock-core/guides +## 0.2.0 + +### Minor Changes + +- [`e69758e`](https://github.com/bedrock-core/apps/commit/e69758e3bf6a58755145d0a357eb657a7497eaf9) Thanks [@drav0011](https://github.com/drav0011)! - A guide opens on its home page, and every page is one press from the index. + + `guide_home` is where a guide opens: the page marked `home: true`, the only page of a single-page + guide, or the index when there is neither. `guide_home_back` is the same entry with a back control, + what a host that opened the guide shows in its place. `guide_index` is the index itself, compiled + once, and exported as `guideIndexScreen`. + + Moving inside a guide replaces rather than stacks. A page's back and its index button both open + `guide_index` in the page's place, and a row of the index opens its page in the index's place. In a + guide with a home page the index's back opens `guide_home_back` in its place, and the home page's + own back leads to wherever the guide was opened from; in a guide with none, the index's back does. + A reader who followed six links is one press from the index. A single-page guide has no index + button, and its back leaves the guide. + + The screen names live in their own module, exported from the package root. The half that BUILDS + the screens and the half that FINDS them in another addon's pack must agree exactly, since a key is + `:` and the two never meet at runtime. + +- [`e69758e`](https://github.com/bedrock-core/apps/commit/e69758e3bf6a58755145d0a357eb657a7497eaf9) Thanks [@drav0011](https://github.com/drav0011)! - **Breaking.** The UI is three peer apps, and each one is a field of `core.register()`. + + `@bedrock-core/config` was the addon list, the config screens and the guide viewer in one mount. + Those are three different things to want, so they are three packages: `@bedrock-core/catalog` + browses every addon in the world, `@bedrock-core/config` holds an addon's settings and the screens + that edit them, and `@bedrock-core/guides` shows its guide. Each installs on its own. + + ```ts + // before + import { ui } from '@bedrock-core/config'; + import { config } from '@bedrock-core/config/server'; + + core.register({ manifest, config: config(definition) }); + ui(core); // the list, the config screens, the guide, and four commands + + // after + import { registerCatalog } from '@bedrock-core/catalog'; + import { registerConfig } from '@bedrock-core/config'; + import { registerGuides } from '@bedrock-core/guides/server'; + + const { config } = core.register({ + manifest, + catalog: registerCatalog(), + config: registerConfig(definition), + guides: registerGuides(), + }); + ``` + + `register()` is the whole mount — there is no second call, and taking two of the three is dropping + a field rather than passing a flag. Each declaration installs its own command, serves its own + `core:.show` method and announces that this addon offers that app, so what a realm can do for + a player follows from what the addon asked for. + + A declaration takes only what the build cannot work out for itself. `registerConfig(definition)` + takes the definition because the definition *is* the declaration: the runtime installs the scopes + from it and the ui-compiler filter reads it out of that very call to shape one screen per section. + `registerCatalog()` and `registerGuides()` take nothing at all — the roster is `core.registry`, and + the guide's pages are already compiled into the pack — so their presence is the entire statement. + Each also takes `{ commands: false }`, which frees the command name without unmounting the app. + + Each app owns one command, under the addon's own namespace: `:config` and `:configat` stay + here, `:catalog` belongs to the catalog (`:list` is gone — vanilla owns `/list`, and the + alias Bedrock grants the first registrant cannot be claimed for a name it already has), and + `:guide` belongs to the guide app. + + Removed from `@bedrock-core/config`, with where each went: + + - `ui`, `openUi` and `UiOptions` — `registerConfig()` mounts, and `config.open(player, target?)` on + the returned accessor is the funnel that `openUi` was. The permission clamp is still behind it. + - `addonPageScreen` and `AddonPageInfo` — the page is `AddonPage` and `AddonPageInfo` on + `@bedrock-core/catalog/compiled`; the addon list, the framework's own row and the page geometry + are internal to the catalog. + - `guideAudienceFor` — removed. + - `registerDeclared` and `DeclaredParts` — `@bedrock-core/navigation`. + - `registerAddonCommands`, `OpenCallback`, `allowedScopes`, `clampTarget`, `isOperator`, + `CONFIG_SCOPES`, `ConfigScope`, `EntrySchema` and `FlatSchemaLike` — internal. + `registerConfig(definition, { commands: false })` with `config.open(player, target?)` makes your + own entry point, and `isOperator` is `@bedrock-core/server`'s. + + `@bedrock-core/config/server` renames its field factory `config` to `registerConfig`, matching the + name the root exports: the two are the same field, one with screens and one without, and an addon + that draws nothing imports the subpath alone. The subsystem reaches the runtime through a + namespaced slot rather than a fixed property — `configOf(core)` reads what the declaration filled + under `core:config`. + + `@bedrock-core/guides` gains `@bedrock-core/guides/server`, the guide app's server half: + `registerGuides`, `guidesOf` and their types. It runs on a bare `Runtime` and draws nothing. The + package root re-exports it beside the screen factories the guides filter's generated modules call, + `openGuide` and `GuideComponents`. `GuideBlockList`, `resolveLanding`, `canSee`, + `hasVisiblePages`, `paginationFor`, `visiblePageIds`, `visibleTree`, `isGuideManifest`, + `guideScreenName` and the manifest types are internal: a guide renders from what the filter + compiles. + +- [`ccd175f`](https://github.com/bedrock-core/apps/commit/ccd175f1f5b74d67c110d5c1125679dda8ce9329) Thanks [@drav0011](https://github.com/drav0011)! - **Breaking.** A paragraph or list item with links is drawn with `Trans`: the build breaks it into the same number of lines in every language, and each link is pressable only where its own text is drawn, in whichever language the client shows. The manifest's `GuideRun` is gone. An inline block carries `k` when it has no links, and when it has, `text` — a tagged string by locale, `See <0>the page.` — and `links`, the page each numbered tag opens, matching the guides filter that writes it. + +- [`ccd175f`](https://github.com/bedrock-core/apps/commit/ccd175f1f5b74d67c110d5c1125679dda8ce9329) Thanks [@drav0011](https://github.com/drav0011)! - A page or category marked `access: op` is shown to world operators only. + + A guide with anything gated is compiled once per audience. `guide_home`, `guide_home_back`, + `guide_index` and `guide_` are what every player is shown: a gated page has no screen there, + the index lists only what a player may open, prev and next skip what they may not, a gated home + page is no home to them, and a link to a gated page, in a paragraph, a list, an admonition or a + component's children, is drawn as text. `guideop_home`, `guideop_home_back`, `guideop_index` and + `guideop_` are the operators' set: every page, and every press inside it leads within it. A + guide with nothing gated compiles the ordinary set alone. + + The entry decides which set a reader walks. `guides.open(player, addonId?)`, the `:guide` + command, a catalog's guide button and `openGuide(ns, player)` open an operator on the operators' + set when the guide has one, and everyone else on the ordinary set. A `` to `guide_home` or + `guide_home_back` is the same press for every viewer, so it always opens the ordinary set. + `openGuide(ns, player, { back: true })` opens the entry with a back control, in the set the player + reads, for a screen that links to a guide. + + The screen factories take `audience: 'op'` for the operators' set, which is what the guides filter + writes, and the manifest carries `opScreens`, each page's screen name in that set. + +- [`ea00fe0`](https://github.com/bedrock-core/apps/commit/ea00fe0a8c94ef9e55c508375f0062293876f954) Thanks [@drav0011](https://github.com/drav0011)! - **Breaking.** A guide is its compiled screens, navigated by key. + + `createGuide` is removed: a page is a screen rather than a state of one. `guideReference`, `presentGuideReference`, `isGuideReference` and `GuideReference` go with it, because a guide's screens ride the ordinary screen table. `openGuide(ns, player)` is a `navigate()`, so it opens this bundle's guide or another addon's the same way. The views take link keys (`linkTo`, `homeTo`) instead of open-page callbacks. + +- [`ea00fe0`](https://github.com/bedrock-core/apps/commit/ea00fe0a8c94ef9e55c508375f0062293876f954) Thanks [@drav0011](https://github.com/drav0011)! - A guide page ships as a table, not as a component. + + A guide page is a static screen: every string it shows is baked and every press it takes is a ``. `GuideBlockList`, `GuidePageView`, `GuideHomeView` and the guide manifest are absent from a built addon, and opening a page is one form call. `openGuide(ns, player)` no longer takes the manifest: it navigates to the guide's key, and the manifest is build input that never reaches the addon. A `cmp` block in a guide may not take a press: somewhere to go is a ``, anything else is decoration. + ## 0.1.0 ### Minor Changes diff --git a/packages/guides/package.json b/packages/guides/package.json index a7b4e42..a59184e 100644 --- a/packages/guides/package.json +++ b/packages/guides/package.json @@ -1,6 +1,6 @@ { "name": "@bedrock-core/guides", - "version": "0.1.0", + "version": "0.2.0", "description": "In-game guide screens for @bedrock-core/ui — renders MDX guides compiled by the guides regolith filter", "keywords": [ "ui",