@cosmicdrift/kumiko-renderer 0.335.0 → 0.336.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/extension-sections.d.ts +3 -3
- package/dist/app/kumiko-screen.js +4 -3
- package/dist/components/related-list-section.js +3 -4
- package/dist/components/render-edit.js +3 -2
- package/dist/components/write-form-section.js +2 -3
- package/dist/hooks/use-report-step-complete.d.ts +2 -0
- package/dist/hooks/use-report-step-complete.js +13 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/primitives.d.ts +15 -2
- package/dist/primitives.js +5 -0
- package/dist/sse/live-events.d.ts +1 -1
- package/package.json +5 -5
- package/src/changes.json +14 -0
|
@@ -57,9 +57,9 @@ export type ExtensionSectionProps = {
|
|
|
57
57
|
};
|
|
58
58
|
/** Only set for extension steps of a `layout.mode: "wizard"` entityEdit
|
|
59
59
|
* editing an existing record (update mode); undefined everywhere else.
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* the
|
|
60
|
+
* Report through `useReportStepComplete(reportStepComplete, complete)`
|
|
61
|
+
* (`null` while the step's data loads) with whether the step already holds
|
|
62
|
+
* its data, so the step bar shows the step as done. */
|
|
63
63
|
readonly reportStepComplete?: (complete: boolean) => void;
|
|
64
64
|
};
|
|
65
65
|
export type ExtensionSectionComponent = ComponentType<ExtensionSectionProps>;
|
|
@@ -959,9 +959,10 @@ function DrawerHost({ schema, drawerAction, drawerScreen, drawerInitialValues, u
|
|
|
959
959
|
closeAndReset();
|
|
960
960
|
}, [hasUnsavedInput, closeAndReset]);
|
|
961
961
|
// Drawer is an optional Core-Primitive (additive rollout) — same "skip +
|
|
962
|
-
// warn
|
|
963
|
-
//
|
|
964
|
-
//
|
|
962
|
+
// warn" precedent as rowActions without a mounted DispatcherProvider above,
|
|
963
|
+
// instead of crashing when a web app hasn't upgraded its createKumikoApp
|
|
964
|
+
// wiring yet. The warning repeats per mount and whenever the action changes.
|
|
965
|
+
// Dev-time setup error, so no dedupe.
|
|
965
966
|
useEffect(() => {
|
|
966
967
|
if (drawerAction !== null && Drawer === undefined) {
|
|
967
968
|
// biome-ignore lint/suspicious/noConsole: dev-warning for a setup error
|
|
@@ -164,10 +164,9 @@ export function RelatedListSection({ section, parentId, record, featureName, tra
|
|
|
164
164
|
}, [ownRefetch, onAfterWrite]);
|
|
165
165
|
const onFilterChange = useCallback((field, values) => setFilters((prev) => ({ ...prev, [field]: values })), []);
|
|
166
166
|
const onFilterReset = useCallback(() => setFilters({}), []);
|
|
167
|
-
// Sorted client-side over the already-loaded rows
|
|
168
|
-
// pager (
|
|
169
|
-
//
|
|
170
|
-
// a client-side sort could misleadingly hide (fw#2722).
|
|
167
|
+
// Sorted client-side over the already-loaded rows only. The section has no
|
|
168
|
+
// pager (one-shot fetch); when that fetch is truncated (`nextCursor` set) the
|
|
169
|
+
// truncation banner below tells the user the sorted set is partial.
|
|
171
170
|
const [sort, setSort] = useState(section.defaultSort ?? null);
|
|
172
171
|
const sortAccessors = useMemo(() => {
|
|
173
172
|
const accessors = {};
|
|
@@ -14,7 +14,7 @@ import { useForm } from "../hooks/use-form.js";
|
|
|
14
14
|
import { useTranslation } from "../i18n.js";
|
|
15
15
|
import { useInsideDrawer } from "../inside-drawer.js";
|
|
16
16
|
import { usePageHeaderCompact, usePageHeaderSlotAvailable } from "../page-header-slot.js";
|
|
17
|
-
import { STICKY_PRIMARY_ACTION_PROP, shouldRenderActionsIconOnly, usePrimitives, } from "../primitives.js";
|
|
17
|
+
import { FOOTER_ACTION_ROLE_PROP, NARROW_LABEL_PROP, STICKY_PRIMARY_ACTION_PROP, shouldRenderActionsIconOnly, usePrimitives, } from "../primitives.js";
|
|
18
18
|
import { GridCellForField } from "./grid-cell-for-field.js";
|
|
19
19
|
import { RelatedListSection } from "./related-list-section.js";
|
|
20
20
|
import { filterEditSections, hasEditableSection, hasIssueWithoutRenderedField, resolveExtensionEntityId, shouldNotifyCaller, } from "./render-edit-logic.js";
|
|
@@ -1107,7 +1107,8 @@ export function RenderEdit(props) {
|
|
|
1107
1107
|
? 1
|
|
1108
1108
|
: 0;
|
|
1109
1109
|
const isSettingsList = screen.layout.variant === "settings-list" && hideSectionTitles !== true;
|
|
1110
|
-
const formActions = (_jsxs(_Fragment, { children: [showWizardBack && (_jsx(Button, { type: "button", variant: "secondary", icon: "chevron-left", onClick: handleWizardBack, testId: "render-edit-wizard-back", children: translate("kumiko.actions.back") })), footerSlot !== undefined && (_jsx(EditSlotMount, { slot: footerSlot, slotName: "footer", screenId: screen.id, entityName: vm.entityName, entityId: resolveExtensionEntityId(entityIdProp, vm.id), values: snapshot.values, hasUnsavedChanges: hasUnsavedInput, wizardStep: isWizard ? { index: currentStep, isLast: isLastWizardStep } : undefined, ...(screen.slots?.footerPrimary === true && { [STICKY_PRIMARY_ACTION_PROP]: true }) })), isWizard && !isLastWizardStep && showsSubmit && !isCreateMode && (_jsx(Button, { type: "button", variant: "ghost", disabled: isSubmitting || disabled, onClick: () => void handleSubmit({ saveNow: true }), testId: "render-edit-wizard-save-close", [STICKY_PRIMARY_ACTION_PROP]: true, children: translate("kumiko.wizard.save-and-close") })), showWizardNext && (_jsx(Button, { type: "submit", variant: "primary", iconEnd: "chevron-right", testId: "render-edit-wizard-next",
|
|
1110
|
+
const formActions = (_jsxs(_Fragment, { children: [showWizardBack && (_jsx(Button, { type: "button", variant: "secondary", icon: "chevron-left", onClick: handleWizardBack, testId: "render-edit-wizard-back", [FOOTER_ACTION_ROLE_PROP]: "back", children: translate("kumiko.actions.back") })), footerSlot !== undefined && (_jsx(EditSlotMount, { slot: footerSlot, slotName: "footer", screenId: screen.id, entityName: vm.entityName, entityId: resolveExtensionEntityId(entityIdProp, vm.id), values: snapshot.values, hasUnsavedChanges: hasUnsavedInput, wizardStep: isWizard ? { index: currentStep, isLast: isLastWizardStep } : undefined, ...(screen.slots?.footerPrimary === true && { [STICKY_PRIMARY_ACTION_PROP]: true }) })), isWizard && !isLastWizardStep && showsSubmit && !isCreateMode && (_jsx(Button, { type: "button", variant: "ghost", disabled: isSubmitting || disabled, onClick: () => void handleSubmit({ saveNow: true }), testId: "render-edit-wizard-save-close", [STICKY_PRIMARY_ACTION_PROP]: true, children: translate("kumiko.wizard.save-and-close") })), showWizardNext && (_jsx(Button, { type: "submit", variant: "primary", iconEnd: "chevron-right", testId: "render-edit-wizard-next", [FOOTER_ACTION_ROLE_PROP]: "primary",
|
|
1111
|
+
[NARROW_LABEL_PROP]: translate("kumiko.actions.next"), children: nextStepTitle !== undefined
|
|
1111
1112
|
? translate("kumiko.wizard.next-with-title", { title: nextStepTitle })
|
|
1112
1113
|
: translate("kumiko.actions.next") })), showSubmit &&
|
|
1113
1114
|
footerActions?.map((action) => (_jsx(Button, { type: "button", variant: action.variant ?? "secondary", ...(action.icon !== undefined && { icon: action.icon }), disabled: isSubmitting || disabled, onClick: () => {
|
|
@@ -100,8 +100,7 @@ export function WriteFormSection({ section, featureName, translate, hideTitle, o
|
|
|
100
100
|
headerActions: titleRowActions,
|
|
101
101
|
}, testId: `write-form-${section.title ?? section.handler}`, children: content }));
|
|
102
102
|
}
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
// aligned footer treatment instead of stretching full-width inline.
|
|
103
|
+
// Submit plus caller actions share the title row's actions slot (submit is
|
|
104
|
+
// lifted into the footer instead when onFooterAction is set).
|
|
106
105
|
return (_jsx(Section, { ...(section.title !== undefined && { title: section.title }), ...(section.description !== undefined && { subtitle: section.description }), ...(section.icon !== undefined && { icon: section.icon }), actions: titleRowActions, testId: `write-form-${section.title ?? section.handler}`, children: content }));
|
|
107
106
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
// Lets an extension wizard step report whether it already holds its data
|
|
3
|
+
// without a raw useEffect in app code (the no-raw-hooks guard forbids those).
|
|
4
|
+
// `complete === null` means the step's data is still loading: nothing is
|
|
5
|
+
// reported, so a loading step never flashes "not done" over a passed-via-Next
|
|
6
|
+
// state. Outside update-mode wizards `reportStepComplete` is undefined and the
|
|
7
|
+
// hook does nothing.
|
|
8
|
+
export function useReportStepComplete(reportStepComplete, complete) {
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (reportStepComplete !== undefined && complete !== null)
|
|
11
|
+
reportStepComplete(complete);
|
|
12
|
+
}, [reportStepComplete, complete]);
|
|
13
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -61,6 +61,7 @@ export type { UseMutationResult } from "./hooks/use-mutation.js";
|
|
|
61
61
|
export { useMutation } from "./hooks/use-mutation.js";
|
|
62
62
|
export type { UseQueryOptions, UseQueryResult } from "./hooks/use-query.js";
|
|
63
63
|
export { entityFromQueryType, useQuery } from "./hooks/use-query.js";
|
|
64
|
+
export { useReportStepComplete } from "./hooks/use-report-step-complete.js";
|
|
64
65
|
export { useStore, useStoreSelector } from "./hooks/use-store.js";
|
|
65
66
|
export type { StreamStatus, UseStreamHandlerOptions, UseStreamHandlerResult, } from "./hooks/use-stream-handler.js";
|
|
66
67
|
export { useStreamHandler } from "./hooks/use-stream-handler.js";
|
|
@@ -69,8 +70,8 @@ export { createStaticLocaleResolver, FormalityProvider, LocaleProvider, mergeTra
|
|
|
69
70
|
export { kumikoDefaultTranslations } from "./i18n-defaults.js";
|
|
70
71
|
export { InsideDrawerProvider, useInsideDrawer } from "./inside-drawer.js";
|
|
71
72
|
export { PageHeaderCompactProvider, PageHeaderSlotAvailableProvider, usePageHeaderCompact, usePageHeaderSlotAvailable, } from "./page-header-slot.js";
|
|
72
|
-
export type { ActionMenuItemSpec, ActionOverflowMenuProps, AppPrimitives, BannerProps, ButtonProps, CardOptions, CardProps, CardSlots, CopyButtonProps, CorePrimitives, DataTableDateRangeFacet, DataTableFacet, DataTableFacetChip, DataTableProps, DataTableRowAction, DataTableRowActionMode, DataTableRowGrouping, DataTableSort, DataTableSortDir, DialogProps, DrawerProps, EmbeddedListCellType, EmbeddedListColumn, EmbeddedListInputProps, EmbeddedListTotal, FieldCellWidth, FieldProps, FillContainerProps, FormProps, FormSectionNavItem, FormWidth, GridCellProps, GridProps, HeadingProps, InputProps, JsonViewProps, LightboxProps, LinkProps, MetricBandProps, MetricProps, ModalProps, PageHeaderProps, PrimitivesProviderProps, PrimitivesRegistry, ProgressProps, ProgressTone, PromoPanelAction, PromoPanelProps, RuntimeRenderer, SecretRevealProps, SecretRevealValue, SectionProps, ShareButtonProps, StatusBadgeProps, StatusTone, StepBarProps, StickyActionBarProps, StickyPrimaryActionMarker, TabsProps, TextProps, TrailingInputAction, WizardStepGroupProps, } from "./primitives.js";
|
|
73
|
-
export { PrimitivesProvider, STICKY_PRIMARY_ACTION_PROP, shouldRenderActionsIconOnly, statusToneForOptionTone, statusToneForValue, usePrimitives, } from "./primitives.js";
|
|
73
|
+
export type { ActionMenuItemSpec, ActionOverflowMenuProps, AppPrimitives, BannerProps, ButtonProps, CardOptions, CardProps, CardSlots, CopyButtonProps, CorePrimitives, DataTableDateRangeFacet, DataTableFacet, DataTableFacetChip, DataTableProps, DataTableRowAction, DataTableRowActionMode, DataTableRowGrouping, DataTableSort, DataTableSortDir, DialogProps, DrawerProps, EmbeddedListCellType, EmbeddedListColumn, EmbeddedListInputProps, EmbeddedListTotal, FieldCellWidth, FieldProps, FillContainerProps, FooterActionMarker, FooterActionRole, FormProps, FormSectionNavItem, FormWidth, GridCellProps, GridProps, HeadingProps, InputProps, JsonViewProps, LightboxProps, LinkProps, MetricBandProps, MetricProps, ModalProps, PageHeaderProps, PrimitivesProviderProps, PrimitivesRegistry, ProgressProps, ProgressTone, PromoPanelAction, PromoPanelProps, RuntimeRenderer, SecretRevealProps, SecretRevealValue, SectionProps, ShareButtonProps, StatusBadgeProps, StatusTone, StepBarProps, StickyActionBarProps, StickyPrimaryActionMarker, TabsProps, TextProps, TrailingInputAction, WizardStepGroupProps, } from "./primitives.js";
|
|
74
|
+
export { FOOTER_ACTION_ROLE_PROP, NARROW_LABEL_PROP, PrimitivesProvider, STICKY_PRIMARY_ACTION_PROP, shouldRenderActionsIconOnly, statusToneForOptionTone, statusToneForValue, usePrimitives, } from "./primitives.js";
|
|
74
75
|
export type { SessionEndedSignal, SessionEndedSignalProviderProps, } from "./session/session-ended.js";
|
|
75
76
|
export { createSessionEndedSignal, isSessionEndedError, SESSION_ENDED_ERROR_CODES, SessionEndedSignalProvider, useSessionEndedSignal, withSessionEndedDetection, } from "./session/session-ended.js";
|
|
76
77
|
export { buildWhatsAppShareUrl } from "./share-links.js";
|
package/dist/index.js
CHANGED
|
@@ -44,13 +44,14 @@ export { useForm } from "./hooks/use-form.js";
|
|
|
44
44
|
export { useListUrlState } from "./hooks/use-list-url-state.js";
|
|
45
45
|
export { useMutation } from "./hooks/use-mutation.js";
|
|
46
46
|
export { entityFromQueryType, useQuery } from "./hooks/use-query.js";
|
|
47
|
+
export { useReportStepComplete } from "./hooks/use-report-step-complete.js";
|
|
47
48
|
export { useStore, useStoreSelector } from "./hooks/use-store.js";
|
|
48
49
|
export { useStreamHandler } from "./hooks/use-stream-handler.js";
|
|
49
50
|
export { createStaticLocaleResolver, FormalityProvider, LocaleProvider, mergeTranslations, translationsByLocaleFromKeys, useFormality, useLocale, useOptionalLocale, useOptionalTranslation, useTranslation, } from "./i18n.js";
|
|
50
51
|
export { kumikoDefaultTranslations } from "./i18n-defaults.js";
|
|
51
52
|
export { InsideDrawerProvider, useInsideDrawer } from "./inside-drawer.js";
|
|
52
53
|
export { PageHeaderCompactProvider, PageHeaderSlotAvailableProvider, usePageHeaderCompact, usePageHeaderSlotAvailable, } from "./page-header-slot.js";
|
|
53
|
-
export { PrimitivesProvider, STICKY_PRIMARY_ACTION_PROP, shouldRenderActionsIconOnly, statusToneForOptionTone, statusToneForValue, usePrimitives, } from "./primitives.js";
|
|
54
|
+
export { FOOTER_ACTION_ROLE_PROP, NARROW_LABEL_PROP, PrimitivesProvider, STICKY_PRIMARY_ACTION_PROP, shouldRenderActionsIconOnly, statusToneForOptionTone, statusToneForValue, usePrimitives, } from "./primitives.js";
|
|
54
55
|
export { createSessionEndedSignal, isSessionEndedError, SESSION_ENDED_ERROR_CODES, SessionEndedSignalProvider, useSessionEndedSignal, withSessionEndedDetection, } from "./session/session-ended.js";
|
|
55
56
|
export { buildWhatsAppShareUrl } from "./share-links.js";
|
|
56
57
|
export { sortByAccessor } from "./sort-by-accessor.js";
|
package/dist/primitives.d.ts
CHANGED
|
@@ -14,6 +14,16 @@ export type DataAttributes = Readonly<Record<`data-${string}`, string>>;
|
|
|
14
14
|
* split can't inspect (see `ScreenSlots.footerPrimary`). */
|
|
15
15
|
export declare const STICKY_PRIMARY_ACTION_PROP: "kumikoStickyPrimaryAction";
|
|
16
16
|
export type StickyPrimaryActionMarker = Partial<Record<typeof STICKY_PRIMARY_ACTION_PROP, boolean>>;
|
|
17
|
+
export type FooterActionRole = "back" | "primary";
|
|
18
|
+
/** Tells the pinned phone footer which node is Back and which is the primary
|
|
19
|
+
* action, for buttons that are not `type="submit"` (e.g. the wizard Back). */
|
|
20
|
+
export declare const FOOTER_ACTION_ROLE_PROP: "kumikoFooterActionRole";
|
|
21
|
+
/** Short label a footer action uses instead of its children below `sm`. */
|
|
22
|
+
export declare const NARROW_LABEL_PROP: "kumikoNarrowLabel";
|
|
23
|
+
export type FooterActionMarker = {
|
|
24
|
+
readonly [FOOTER_ACTION_ROLE_PROP]?: FooterActionRole;
|
|
25
|
+
readonly [NARROW_LABEL_PROP]?: string;
|
|
26
|
+
};
|
|
17
27
|
/** Standard-Button. `loading` zeigt einen Spinner statt der Children
|
|
18
28
|
* und sollte mit `disabled` kombiniert werden, wenn die Action wirklich
|
|
19
29
|
* blockiert bis das Loading durch ist (z.B. async submit). Native-
|
|
@@ -1157,7 +1167,9 @@ export type ProgressProps = {
|
|
|
1157
1167
|
* buttons (every non-current step with `selectableSteps: "all"`); the caller
|
|
1158
1168
|
* owns the validation gate for forward jumps. Implementations render a
|
|
1159
1169
|
* narrow-viewport fallback showing `compactLabel` instead (caller
|
|
1160
|
-
* supplies it pre-translated, e.g. "Step 2 of 5 · Industry")
|
|
1170
|
+
* supplies it pre-translated, e.g. "Step 2 of 5 · Industry"). With
|
|
1171
|
+
* `onStepSelect` and `selectableSteps: "all"` that fallback is a dropdown
|
|
1172
|
+
* listing all steps so narrow viewports can jump too — which of
|
|
1161
1173
|
* the two is visible is a responsive layout choice owned by the
|
|
1162
1174
|
* implementation, not this contract. */
|
|
1163
1175
|
export type StepBarProps = {
|
|
@@ -1169,7 +1181,8 @@ export type StepBarProps = {
|
|
|
1169
1181
|
* index is below `currentIndex`. The current step is never done. */
|
|
1170
1182
|
readonly doneSteps?: readonly boolean[];
|
|
1171
1183
|
/** "done" (default): only done steps are jump targets. "all": every
|
|
1172
|
-
* non-current step is, when `onStepSelect` is set
|
|
1184
|
+
* non-current step is, when `onStepSelect` is set; the compact label then
|
|
1185
|
+
* becomes a step picker. */
|
|
1173
1186
|
readonly selectableSteps?: "done" | "all";
|
|
1174
1187
|
/** "label" (default) swaps the step row for `compactLabel` on narrow
|
|
1175
1188
|
* viewports; "steps" keeps the row there too — for short wizards whose
|
package/dist/primitives.js
CHANGED
|
@@ -6,6 +6,11 @@ import { createContext, useContext, } from "react";
|
|
|
6
6
|
* footer-slot mount, whose actual rendered button is opaque app code the
|
|
7
7
|
* split can't inspect (see `ScreenSlots.footerPrimary`). */
|
|
8
8
|
export const STICKY_PRIMARY_ACTION_PROP = "kumikoStickyPrimaryAction";
|
|
9
|
+
/** Tells the pinned phone footer which node is Back and which is the primary
|
|
10
|
+
* action, for buttons that are not `type="submit"` (e.g. the wizard Back). */
|
|
11
|
+
export const FOOTER_ACTION_ROLE_PROP = "kumikoFooterActionRole";
|
|
12
|
+
/** Short label a footer action uses instead of its children below `sm`. */
|
|
13
|
+
export const NARROW_LABEL_PROP = "kumikoNarrowLabel";
|
|
9
14
|
/** Teil-C action-icon collapse rule: a group of more than two actions where
|
|
10
15
|
* every member carries an icon renders icon-only instead of wall-to-wall
|
|
11
16
|
* text buttons; any icon-less member keeps the whole group on text so it
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.336.1",
|
|
4
4
|
"description": "Platform-agnostic React renderer for Kumiko screens. Contains the shared logic — primitives-contract, hooks, KumikoScreen, navigation & SSE abstractions — that any platform-specific renderer (web, native) composes. No DOM, no EventSource, no react-dom.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
19
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
20
|
-
"@cosmicdrift/kumiko-types": "0.
|
|
18
|
+
"@cosmicdrift/kumiko-framework": "0.336.1",
|
|
19
|
+
"@cosmicdrift/kumiko-headless": "0.336.1",
|
|
20
|
+
"@cosmicdrift/kumiko-types": "0.336.1",
|
|
21
21
|
"react": "^19.2.6",
|
|
22
22
|
"temporal-polyfill": "^0.3.2",
|
|
23
23
|
"zod": "^4.4.3"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@types/react-dom": "^19.2.3",
|
|
29
29
|
"jsdom": "^29.1.1",
|
|
30
30
|
"react-dom": "^19.2.6",
|
|
31
|
-
"@cosmicdrift/kumiko-locale-de": "0.
|
|
31
|
+
"@cosmicdrift/kumiko-locale-de": "0.336.1"
|
|
32
32
|
},
|
|
33
33
|
"repository": {
|
|
34
34
|
"type": "git",
|
package/src/changes.json
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.336.0",
|
|
4
|
+
"type": "breaking",
|
|
5
|
+
"title": "LiveEvent data has no payload, it carries eventType",
|
|
6
|
+
"detail": "`LiveEvent.data` is now `{ id, aggregateType, eventType, version, createdAt }`. The server sends signals only, so consumers refetch through a query.",
|
|
7
|
+
"migration": "Replace reads of `event.data.payload` with a query refetch. `useQuery({ live: true })` already does this and needs no change."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"version": "0.336.0",
|
|
11
|
+
"type": "improvement",
|
|
12
|
+
"title": "useReportStepComplete reports an extension wizard step's completeness without a raw useEffect",
|
|
13
|
+
"detail": "`useReportStepComplete(props.reportStepComplete, complete)` with `complete: boolean | null`. `null` reports nothing (data loading), a boolean is reported whenever it changes. Outside update-mode wizards `reportStepComplete` is undefined and the hook does nothing.",
|
|
14
|
+
"migration": "Extension steps that call `reportStepComplete` from a `useEffect` should switch to `useReportStepComplete(reportStepComplete, complete)`; app repos need this to pass the no-raw-hooks guard."
|
|
15
|
+
},
|
|
2
16
|
{
|
|
3
17
|
"version": "0.335.0",
|
|
4
18
|
"type": "fix",
|