@octanejs/cli 0.0.5 → 0.0.7
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/package.json +1 -1
- package/src/commands/add.js +2 -1
- package/src/commands/init/index.js +14 -3
- package/src/commands/init/templates.js +2 -2
- package/src/data/octane-data.json +107 -53
- package/src/kernel/install.js +67 -9
package/package.json
CHANGED
package/src/commands/add.js
CHANGED
|
@@ -90,7 +90,8 @@ export default defineCommand({
|
|
|
90
90
|
} else {
|
|
91
91
|
const spinner = ctx.ui.spinner(`Installing ${toInstall.join(', ')}`);
|
|
92
92
|
const ran = await installPackages(ctx, project, toInstall, { dev: input.flags.dev });
|
|
93
|
-
spinner.stop(ran);
|
|
93
|
+
spinner.stop(ran.command);
|
|
94
|
+
if (ran.warnings.length > 0) ctx.ui.note('Do this by hand', ran.warnings);
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
|
|
@@ -3,7 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import { defineCommand } from '../../kernel/command.js';
|
|
4
4
|
import { setCompilerOption } from '../../kernel/edit.js';
|
|
5
5
|
import { CliError, EXIT } from '../../kernel/errors.js';
|
|
6
|
-
import { PACKAGE_MANAGERS, installPackages } from '../../kernel/install.js';
|
|
6
|
+
import { PACKAGE_MANAGERS, PNPM_ALLOWED_BUILDS, installPackages } from '../../kernel/install.js';
|
|
7
7
|
import {
|
|
8
8
|
MODES,
|
|
9
9
|
PRETTIER_CONFIG_FILES,
|
|
@@ -458,6 +458,11 @@ export async function applyInit(ctx, project, options) {
|
|
|
458
458
|
|
|
459
459
|
/** @type {string[]} */
|
|
460
460
|
const installed = [];
|
|
461
|
+
// Every install in this run hits the same blocked build script, and the same
|
|
462
|
+
// line three times reads like three problems.
|
|
463
|
+
const warn = (/** @type {string[]} */ lines) => {
|
|
464
|
+
for (const line of lines) if (!manual.includes(line)) manual.push(line);
|
|
465
|
+
};
|
|
461
466
|
if (options.install !== false && dependencies.length + devDependencies.length > 0) {
|
|
462
467
|
const spinner = ctx.ui.spinner(`Installing with ${installing.packageManager ?? 'npm'}`);
|
|
463
468
|
try {
|
|
@@ -466,9 +471,11 @@ export async function applyInit(ctx, project, options) {
|
|
|
466
471
|
[devDependencies, true],
|
|
467
472
|
]) {
|
|
468
473
|
if (/** @type {string[]} */ (names).length === 0) continue;
|
|
469
|
-
await installPackages(ctx, installing, /** @type {string[]} */ (names), {
|
|
474
|
+
const ran = await installPackages(ctx, installing, /** @type {string[]} */ (names), {
|
|
470
475
|
dev: Boolean(dev),
|
|
476
|
+
allowBuilds: PNPM_ALLOWED_BUILDS,
|
|
471
477
|
});
|
|
478
|
+
warn(ran.warnings);
|
|
472
479
|
installed.push(.../** @type {string[]} */ (names));
|
|
473
480
|
}
|
|
474
481
|
|
|
@@ -481,7 +488,11 @@ export async function applyInit(ctx, project, options) {
|
|
|
481
488
|
if (range === null) {
|
|
482
489
|
manual.push('Install typescript, at the range @tsrx/typescript-plugin declares.');
|
|
483
490
|
} else {
|
|
484
|
-
await installPackages(ctx, installing, [`typescript@${range}`], {
|
|
491
|
+
const ran = await installPackages(ctx, installing, [`typescript@${range}`], {
|
|
492
|
+
dev: true,
|
|
493
|
+
allowBuilds: PNPM_ALLOWED_BUILDS,
|
|
494
|
+
});
|
|
495
|
+
warn(ran.warnings);
|
|
485
496
|
installed.push('typescript');
|
|
486
497
|
}
|
|
487
498
|
}
|
|
@@ -593,12 +593,12 @@ export const indexHtml = (mode) => (mode === 'fullstack' ? SSR_INDEX_HTML : SPA_
|
|
|
593
593
|
/**
|
|
594
594
|
* The client bootstrap, `spa` only. `render(App)` is the body-and-props
|
|
595
595
|
* overload, which keeps the entry plain TypeScript with no JSX pragma to carry.
|
|
596
|
+
* Chaining the disposable mount lets eligible builds omit reusable-root machinery.
|
|
596
597
|
*/
|
|
597
598
|
export const clientEntry = `import { createRoot } from "octane";
|
|
598
599
|
import { App } from "./App.tsrx";
|
|
599
600
|
|
|
600
|
-
|
|
601
|
-
root.render(App);
|
|
601
|
+
createRoot(document.getElementById("root")!).render(App);
|
|
602
602
|
`;
|
|
603
603
|
|
|
604
604
|
/**
|
|
@@ -1,8 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bindings": [
|
|
3
|
+
{
|
|
4
|
+
"name": "@octanejs/animejs",
|
|
5
|
+
"version": "0.0.2",
|
|
6
|
+
"category": "UI and interaction",
|
|
7
|
+
"upstream": {
|
|
8
|
+
"package": "animejs",
|
|
9
|
+
"version": "4.5.0",
|
|
10
|
+
"source": "https://github.com/juliangarnier/anime/tree/v4.5.0",
|
|
11
|
+
"license": "MIT"
|
|
12
|
+
},
|
|
13
|
+
"surface": "Anime.js is re-exported unchanged; `useAnimeScope` binds scoped DOM animation setup, refresh, dependency recreation, and cleanup to Octane, and `@octanejs/animejs/adapters/three` exposes Anime.js's official Three adapter.",
|
|
14
|
+
"divergences": [
|
|
15
|
+
"`useAnimeScope` is an Octane-native lifecycle helper; it is not an upstream Anime.js API.",
|
|
16
|
+
"Only the root and `adapters/three` entry points are re-exported; other Anime.js subpaths are explicit gaps whose APIs remain available from the supported root where upstream exposes them there.",
|
|
17
|
+
"The Three adapter mutates raw objects while `@octanejs/three` retains frame-loop ownership; demand and never loops require explicit invalidation or advancement."
|
|
18
|
+
],
|
|
19
|
+
"ssr": "Supported. The hook returns inert refs during server rendering and creates no Anime.js scope until its client effect runs.",
|
|
20
|
+
"verified": "2026-07-30"
|
|
21
|
+
},
|
|
3
22
|
{
|
|
4
23
|
"name": "@octanejs/apollo-client",
|
|
5
|
-
"version": "0.1.
|
|
24
|
+
"version": "0.1.27",
|
|
6
25
|
"category": "AI, data, and routing",
|
|
7
26
|
"upstream": { "package": "@apollo/client", "version": "4.2.6" },
|
|
8
27
|
"surface": "Complete published client adapter surface: all 18 @apollo/client/react runtime exports and their Apollo 4.2.6 TypeScript declarations, framework-neutral root/testing exports, an Octane MockedProvider, and the Octane-native /react/ssr prerenderStatic entry.",
|
|
@@ -16,7 +35,7 @@
|
|
|
16
35
|
},
|
|
17
36
|
{
|
|
18
37
|
"name": "@octanejs/aria",
|
|
19
|
-
"version": "0.0.
|
|
38
|
+
"version": "0.0.26",
|
|
20
39
|
"category": "UI and interaction",
|
|
21
40
|
"upstream": { "package": "react-aria", "version": "3.50.0" },
|
|
22
41
|
"surface": "Phases 0-5 + the Tree/Table follow-up complete. Phases 0-1: the utils foundation, SSR utilities, the complete interactions area (usePress, useHover, focus/keyboard family, useLongPress, useMove, Pressable/PressResponder), the focus area (FocusScope with containment/restore/focus managers, FocusRing, useFocusRing, useHasTabbableChild), the i18n area (I18nProvider, locale/collator/formatter/filter hooks), form validation (useFormValidation + stately useFormValidationState), and the leaf hooks: useButton/useToggleButton(+Group), useLabel/useField, useCheckbox(+Group/+Item), useRadio/useRadioGroup, useSwitch, useTextField, useSearchField, useProgressBar, useMeter, useSeparator, useLink, useDisclosure, useToolbar, VisuallyHidden. Phase 2 adds the collections + selection tier: the stately collections engine (CollectionBuilder/Item/Section/useCollection) and selection core (Selection/SelectionManager/useMultipleSelectionState), the stately state hooks (useListState/useSingleSelectListState, useTreeState, useMenuTriggerState/useSubmenuTriggerState, useOverlayTriggerState, useSelectState, useComboBoxState, useTabListState, useNumberFieldState, useSliderState), the aria selection area (useSelectableCollection/-Item/-List, useTypeSelect, ListKeyboardDelegate, DOMLayoutDelegate), and the aria hooks useListBox/useOption/useListBoxSection, useMenu/useMenuItem/useMenuSection/useMenuTrigger/useSubmenuTrigger, useTab/useTabList/useTabPanel, useSlider/useSliderThumb, useNumberField, useGridList(+Item/+Section/+SelectionCheckbox), useTag/useTagGroup, useBreadcrumbs/useBreadcrumbItem — plus the matching react-stately state hooks under `@octanejs/aria/stately`. Phase 3 adds the overlays hooks tier: the stately `useTooltipTriggerState` and the whole aria overlays area (usePreventScroll, ariaHideOutside, DismissButton, PortalProvider, useOverlay, useOverlayTrigger, useOverlayPosition + calculatePosition, Overlay/useOverlayFocusContain, useModal/ModalProvider/OverlayProvider/OverlayContainer, useModalOverlay, usePopover), plus the consumers useDialog, useTooltip/useTooltipTrigger, useSelect/useHiddenSelect/HiddenSelect, and useComboBox. Differential-verified byte-identical against the real react-aria (interactions + button/toggle/checkbox/switch/radio/textfield/progress + tabs + listbox + select + combobox fixtures); dialog/tooltip/overlay focus-trap/dismiss/scroll-lock paths are covered by behavioral tests (the differential rig shares one document, so focus/portal/positioning aren't rig-driveable). Autocomplete (useAutocomplete/useSearchAutocomplete) is deferred — useComboBox does not depend on it in 3.50.0. Phase 4 adds the react-aria-components foundation under `@octanejs/aria/components`: the collections engine re-hosted on a detached real-DOM store (BaseCollection/CollectionBuilder/createLeafComponent/createBranchComponent/Hidden/useCachedChildren + Collection/Section), the RAC plumbing (Provider, useContextProps, slotted contexts, useRenderProps/composeRenderProps with data-* state attributes), and the non-collection components: Button, ToggleButton(+Group), Checkbox(+Group/Field/Button), Switch(+Field/Button), RadioGroup(+Radio/Field/Button), TextField, SearchField, NumberField, Form, Label/Input/TextArea/FieldError, Group, Toolbar, Separator, Header, Heading, Link, ProgressBar, Meter, Slider(+Output/Track/Thumb/Fill), Disclosure(+Group/Panel), DialogTrigger/Dialog, Modal/ModalOverlay, Popover, TooltipTrigger/Tooltip, OverlayArrow, Text, Keyboard, SelectionIndicator, SharedElementTransition. Phase-4 differentials drive the REAL components on both sides byte-identical (Button hover+mid-press, ToggleButton, Checkbox, TextField typing, Disclosure expand/collapse). Phase 5 adds the RAC collection components over that engine: Autocomplete (full — aria useAutocomplete + stately useAutocompleteState now ported), ListBox(+Item/Section/LoadMoreItem), Menu(+MenuTrigger/SubmenuTrigger/MenuItem/MenuSection), Select(+SelectValue), ComboBox(+ComboBoxValue), Tabs(+TabList/Tab/TabPanels/TabPanel), TagGroup(+TagList/Tag), GridList(+Item/Section/Header/LoadMoreItem), Breadcrumbs(+Breadcrumb), and the DragAndDrop context layer (DropIndicator/contexts/DragAndDropHooks type; components' dnd branches are inert — the dnd engine and useDragAndDrop() itself arrive in a later phase, the stub throws). Phase-5 differentials drive the REAL react-aria-components byte-identical (ListBox selection + keyed reverse, Tabs switch, TagGroup multi-select, GridList row selection, Breadcrumbs, ComboBox typing); Menu/Select open-state (portal'd) carries behavioral coverage incl. keyboard-driven submenus. The Tree/Table follow-up adds the remaining collection verticals: stately grid (GridCollection/useGridState) + the full stately table area (TableCollection/useTableState/column-resize state/UNSTABLE_useTreeGridState), the aria tree hooks (useTree/useTreeItem) and the full aria table hook area (useTable family, TableKeyboardDelegate, useTableColumnResize, grid hooks it rides on), RAC Tree(+TreeItem/TreeItemContent/TreeSection/TreeHeader/TreeLoadMoreItem) and RAC Table(+TableHeader/TableBody/Column/Row/Cell/ColumnResizer/ResizableTableContainer/TableFooter/TableLoadMoreItem). Tree structure states and the interactive Table (sort cycling, row selection) are differential-verified byte-identical vs the real react-aria-components; chevron-driven Tree interaction carries behavioral coverage (the rig's virtual clicks cannot faithfully reproduce the focus-effect interplay on the React side). TableLayout lands with the Virtualizer; date/color families and the drag-and-drop engine are not started — see the migration plan.",
|
|
@@ -31,7 +50,7 @@
|
|
|
31
50
|
},
|
|
32
51
|
{
|
|
33
52
|
"name": "@octanejs/base-ui",
|
|
34
|
-
"version": "0.1.
|
|
53
|
+
"version": "0.1.30",
|
|
35
54
|
"category": "UI and interaction",
|
|
36
55
|
"upstream": { "package": "@base-ui/react", "version": "1.6.0" },
|
|
37
56
|
"surface": "Alpha, in progress: 34 of 43 upstream subpaths. The foundation, overlay infrastructure, hover/focus interaction layer, list-navigation/typeahead layer and popup viewport have landed, along with Dialog, AlertDialog, Popover, Tooltip, PreviewCard, the full form-control set, and the standalone Button/DirectionProvider/CSPProvider/useMediaQuery utilities — ported at full fidelity and differential-verified against the real `@base-ui/react`. Menu is COMPLETE at all 20 upstream parts — Root/Trigger/Portal/Positioner/Popup, the full item family (Item, LinkItem, CheckboxItem, RadioGroup/RadioItem and their indicators, Group/GroupLabel, Separator), Arrow, Backdrop, Viewport, and SubmenuRoot/SubmenuTrigger. Menubar and ContextMenu have landed too, so the whole menu family is complete. Toast is complete at all 11 parts, including the imperative toast manager, auto-dismiss timers with hover/focus pausing, and promise toasts; swipe-to-dismiss is covered too. Collapsible is complete at all 3 upstream parts (Root/Trigger/Panel), including upstream's <Activity> animation-resume suppression — octane's Activity has React's contract (hidden subtrees keep state and DOM while effects tear down and re-fire on reveal), so that path is ported rather than skipped and is the first component carrying a port of Base UI's OWN test file, under tests/upstream/ — 16 of its 35 upstream cases, being every case that does not require real layout measurement, CSS transition/keyframe sequencing, React.Activity, or find-in-page `beforematch`. Accordion is complete at all 5 upstream parts (Root/Item/Header/Trigger/Panel), built directly on Collapsible — each Item runs its own useCollapsibleRoot and provides CollapsibleRootContext, exactly as upstream does. It carries 18 tests: 15 ported from upstream's own suite plus 3 written to close a real gap — upstream only exercises single-vs-multiple toggling inside jsdom-skipped blocks, so removing the single-mode collapse branch passed every ported case.",
|
|
@@ -47,7 +66,7 @@
|
|
|
47
66
|
},
|
|
48
67
|
{
|
|
49
68
|
"name": "@octanejs/cmdk",
|
|
50
|
-
"version": "0.1.
|
|
69
|
+
"version": "0.1.15",
|
|
51
70
|
"category": "UI and interaction",
|
|
52
71
|
"upstream": { "package": "cmdk", "version": "1.1.1" },
|
|
53
72
|
"surface": "Complete against the published `cmdk@1.1.1` public surface: `Command` (the root itself) and the `CommandRoot` named export, `Command.Input`, `Command.List`, `Command.Item`, `Command.Group`, `Command.Separator`, `Command.Dialog`, `Command.Empty`, `Command.Loading`, the flat `CommandX` aliases, `useCommandState`, and `defaultFilter` — with the DOM-authoritative store and item/group registration, `useValue` text-content inference, `onInput`-driven search, score filtering plus item and group DOM sorting, keyboard navigation (arrows/Home/End/vim/Enter), controlled `value`/`onValueChange`/`loop`/`shouldFilter`/custom `filter`/`forceMount`, the `--cmdk-list-height` ResizeObserver, and a Radix-backed `Command.Dialog`. `asChild` is the one unsupported prop (see divergences).",
|
|
@@ -78,7 +97,7 @@
|
|
|
78
97
|
},
|
|
79
98
|
{
|
|
80
99
|
"name": "@octanejs/devtools",
|
|
81
|
-
"version": "0.0.
|
|
100
|
+
"version": "0.0.20",
|
|
82
101
|
"category": "Styling, tests, and devtools",
|
|
83
102
|
"upstream": { "package": "octane", "version": "workspace" },
|
|
84
103
|
"surface": "Octane-native DevTools plugin (not an upstream port): renders live runtime diagnostics into a TanStack Devtools host via @tanstack/devtools-event-client. P1 ships the Components tree + state inspector.",
|
|
@@ -88,7 +107,7 @@
|
|
|
88
107
|
},
|
|
89
108
|
{
|
|
90
109
|
"name": "@octanejs/dexie",
|
|
91
|
-
"version": "0.1.
|
|
110
|
+
"version": "0.1.25",
|
|
92
111
|
"category": "AI, data, and routing",
|
|
93
112
|
"upstream": { "package": "dexie-react-hooks", "version": "4.4.0" },
|
|
94
113
|
"surface": "Port of the public dexie-react-hooks surface: useObservable, useLiveQuery, useSuspendingObservable, useSuspendingLiveQuery, usePermissions, and useDocument, with Dexie's framework-neutral API re-exported from the package root.",
|
|
@@ -102,7 +121,7 @@
|
|
|
102
121
|
},
|
|
103
122
|
{
|
|
104
123
|
"name": "@octanejs/dnd-kit",
|
|
105
|
-
"version": "0.1.
|
|
124
|
+
"version": "0.1.27",
|
|
106
125
|
"category": "UI and interaction",
|
|
107
126
|
"upstream": { "package": "@dnd-kit/react", "version": "0.5.0" },
|
|
108
127
|
"surface": "Complete modern dnd-kit React-adapter surface: DragDropProvider, DragOverlay, useDraggable/useDroppable, manager/monitor/operation hooks, PointerSensor/KeyboardSensor re-exports, the public signal-hook utilities, useSortable, and all four upstream entry points.",
|
|
@@ -115,7 +134,7 @@
|
|
|
115
134
|
},
|
|
116
135
|
{
|
|
117
136
|
"name": "@octanejs/electron",
|
|
118
|
-
"version": "0.0.
|
|
137
|
+
"version": "0.0.10",
|
|
119
138
|
"category": "Desktop",
|
|
120
139
|
"upstream": { "package": "electron", "version": "43.2.0" },
|
|
121
140
|
"surface": "Process-split Electron bindings: ./main registers ipcMain handlers, ./main/native re-exports main-only Electron APIs (Menu, Tray, session, protocol, BrowserWindow, …), ./preload exposes Electron IPC and desktop helpers via contextBridge, and the renderer entry provides Octane hooks (useInvoke, useInvokeState, useIpcEvent, useNativeTheme, useWindowState) plus promise helpers for app/window/dialog/shell/clipboard/screen. Menu/Tray/session/protocol stay intentional main-only under contextIsolation.",
|
|
@@ -133,7 +152,7 @@
|
|
|
133
152
|
},
|
|
134
153
|
{
|
|
135
154
|
"name": "@octanejs/floating-ui",
|
|
136
|
-
"version": "0.1.
|
|
155
|
+
"version": "0.1.31",
|
|
137
156
|
"category": "UI and interaction",
|
|
138
157
|
"upstream": { "package": "@floating-ui/react", "version": "0.27.19" },
|
|
139
158
|
"surface": "Positioning (`useFloating`, ref-aware `arrow`, the `@floating-ui/dom` middleware re-exports, the floating tree), the full interaction-hook set (`useInteractions`, `useHover` + `safePolygon`, `useClick`, `useFocus`, `useDismiss`, `useRole`, `useClientPoint`, `useListNavigation`, `useTypeahead`), the component layer (`FloatingPortal`, `FloatingOverlay`, `FloatingFocusManager`, `FloatingArrow`, `FloatingList`, `Composite`), and transitions + `FloatingDelayGroup`.",
|
|
@@ -143,7 +162,7 @@
|
|
|
143
162
|
},
|
|
144
163
|
{
|
|
145
164
|
"name": "@octanejs/hook-form",
|
|
146
|
-
"version": "0.1.
|
|
165
|
+
"version": "0.1.29",
|
|
147
166
|
"category": "Forms and content",
|
|
148
167
|
"upstream": { "package": "react-hook-form", "version": "7.81.0" },
|
|
149
168
|
"surface": "Complete port of react-hook-form 7.81.0 (tag commit 46b217e034dd92f7aa3cb3a478815556b416b299). The automated parity check runs all 1,193 original tests against the pinned React package as a pristine baseline; the Octane port separately runs byte-locked, unfiltered DOM and server suites with exact collected/executed inventories containing 1,187 entries representing 1,178 unique file/full-name identities. The nine duplicate entries are repeated titles within the DOM inventory; the server inventory is disjoint. Coverage includes `useForm`, `useController`, `useFieldArray`, `useFormState`, `useWatch`, `useFormContext`/`FormProvider`, schema resolvers, and all validation modes.",
|
|
@@ -156,7 +175,7 @@
|
|
|
156
175
|
},
|
|
157
176
|
{
|
|
158
177
|
"name": "@octanejs/i18next",
|
|
159
|
-
"version": "0.1.
|
|
178
|
+
"version": "0.1.27",
|
|
160
179
|
"category": "Forms and content",
|
|
161
180
|
"upstream": { "package": "react-i18next", "version": "17.0.9" },
|
|
162
181
|
"surface": "Complete runtime port of react-i18next 17.0.9: useTranslation, I18nextProvider/context, Trans/TransWithoutContext, IcuTrans/IcuTransWithoutContext, Translation, the withTranslation/withSSR HOCs, useSSR, namespace reporting, initialization/default helpers, and the root ICU helper exports over the unchanged i18next core.",
|
|
@@ -171,7 +190,7 @@
|
|
|
171
190
|
},
|
|
172
191
|
{
|
|
173
192
|
"name": "@octanejs/jotai",
|
|
174
|
-
"version": "0.1.
|
|
193
|
+
"version": "0.1.29",
|
|
175
194
|
"category": "Shared state",
|
|
176
195
|
"upstream": { "package": "jotai", "version": "2.20.2" },
|
|
177
196
|
"surface": "Complete 1:1 port: the framework-agnostic vanilla core (`jotai/vanilla`, `/vanilla/utils`, `/vanilla/internals`) is reused verbatim; the React layer (`Provider`, `useStore`, `useAtom`, `useAtomValue`, `useSetAtom`) and `react/utils` (`useResetAtom`, `useReducerAtom`, `useAtomCallback`, `useHydrateAtoms`) are ported onto octane hooks, preserving upstream's useReducer force-update + effect-subscription implementation, async atoms via octane's `use()`.",
|
|
@@ -181,7 +200,7 @@
|
|
|
181
200
|
},
|
|
182
201
|
{
|
|
183
202
|
"name": "@octanejs/lexical",
|
|
184
|
-
"version": "0.1.
|
|
203
|
+
"version": "0.1.31",
|
|
185
204
|
"category": "Forms and content",
|
|
186
205
|
"upstream": { "package": "@lexical/react", "version": "0.46.0" },
|
|
187
206
|
"surface": "35 of 39 `@lexical/react` modules ported: composer + contexts, the editable surface, plain/rich text, and the full plugin/menu set (history, lists + check-list, links, tables, markdown shortcuts, the typeahead/node-menu/context-menu family, draggable-block, character-limit, …) plus the `useLexical*` hooks.",
|
|
@@ -192,9 +211,23 @@
|
|
|
192
211
|
"ssr": "No dedicated SSR/hydration tests.",
|
|
193
212
|
"verified": "2026-07-09"
|
|
194
213
|
},
|
|
214
|
+
{
|
|
215
|
+
"name": "@octanejs/livestore",
|
|
216
|
+
"version": "0.0.2",
|
|
217
|
+
"category": "AI, data, and routing",
|
|
218
|
+
"upstream": { "package": "@livestore/react", "version": "0.4.0" },
|
|
219
|
+
"surface": "Ports the complete stable renderer surface (registry provider/access, Suspense store loading and augmentation, reactive queries, client documents, and sync status) plus the exported experimental LiveList over LiveStore's unchanged 0.4.0 framework-neutral packages.",
|
|
220
|
+
"divergences": [
|
|
221
|
+
"ReactApi and withReactApi retain their historical upstream names but attach Octane hooks.",
|
|
222
|
+
"The public query error label identifies octane; LiveStore framework-toolkit 0.4.0 still records its internal refresh-reason renderer tag as react.",
|
|
223
|
+
"React Strict Mode double invocation is not emulated."
|
|
224
|
+
],
|
|
225
|
+
"ssr": "Supported at the binding boundary: server rendering reads existing synchronous state without running passive subscriptions or browser-only store work; client Suspense and hydration are covered separately.",
|
|
226
|
+
"verified": "2026-08-02"
|
|
227
|
+
},
|
|
195
228
|
{
|
|
196
229
|
"name": "@octanejs/lucide",
|
|
197
|
-
"version": "0.1.
|
|
230
|
+
"version": "0.1.27",
|
|
198
231
|
"category": "UI and interaction",
|
|
199
232
|
"upstream": { "package": "lucide-react", "version": "1.24.0" },
|
|
200
233
|
"surface": "Complete against the published `lucide-react@1.24.0` runtime surface: every canonical icon and alias, the `icons` namespace, `Icon`, `createLucideIcon`, `LucideProvider`, `useLucideContext`, `DynamicIcon`, `iconNames`, `dynamicIconImports`, and per-icon subpath imports.",
|
|
@@ -207,7 +240,7 @@
|
|
|
207
240
|
},
|
|
208
241
|
{
|
|
209
242
|
"name": "@octanejs/mantine-hooks",
|
|
210
|
-
"version": "0.1.
|
|
243
|
+
"version": "0.1.13",
|
|
211
244
|
"category": "UI and interaction",
|
|
212
245
|
"upstream": { "package": "@mantine/hooks", "version": "9.5.0" },
|
|
213
246
|
"surface": "Complete @mantine/hooks 9.5.0 runtime export surface: state, timing, storage, viewport, input, focus, pointer, observer, hotkey, scrolling, collapse, drag, splitter, mask, and utility hooks.",
|
|
@@ -221,7 +254,7 @@
|
|
|
221
254
|
},
|
|
222
255
|
{
|
|
223
256
|
"name": "@octanejs/mdx",
|
|
224
|
-
"version": "0.1.
|
|
257
|
+
"version": "0.1.29",
|
|
225
258
|
"category": "Forms and content",
|
|
226
259
|
"upstream": { "package": "@mdx-js/mdx", "version": "3.1.1" },
|
|
227
260
|
"surface": "The full compile-don't-interpret pipeline: `.mdx`/`.md` → `@mdx-js/mdx` (reused verbatim) → octane compiler, via the `octaneMdx()` Vite plugin plus the `./compile` and `./server` entries; compiler warnings propagate through direct and Vite compile surfaces with authored `.mdx` ranges; `@mdx-js/react`'s provider layer (`MDXProvider`/`useMDXComponents`) is ported onto octane context. The octane website runs on it.",
|
|
@@ -233,7 +266,7 @@
|
|
|
233
266
|
},
|
|
234
267
|
{
|
|
235
268
|
"name": "@octanejs/mobx",
|
|
236
|
-
"version": "0.1.
|
|
269
|
+
"version": "0.1.13",
|
|
237
270
|
"category": "Shared state",
|
|
238
271
|
"upstream": { "package": "mobx-react-lite", "version": "4.1.1", "core": "mobx@6.16.1" },
|
|
239
272
|
"surface": "The framework-independent MobX core is re-exported verbatim. The function-component binding includes observer, Observer, useObserver, useLocalObservable, enableStaticRendering, isUsingStaticRendering, and the deprecated useStaticRendering alias.",
|
|
@@ -247,7 +280,7 @@
|
|
|
247
280
|
},
|
|
248
281
|
{
|
|
249
282
|
"name": "@octanejs/motion",
|
|
250
|
-
"version": "0.1.
|
|
283
|
+
"version": "0.1.31",
|
|
251
284
|
"category": "UI and interaction",
|
|
252
285
|
"upstream": { "package": "motion", "version": "12.42.2" },
|
|
253
286
|
"surface": "Core surface: `motion.<tag>` (animate, gestures, variants with propagation/stagger, drag, layout basics), `AnimatePresence`, `MotionConfig`, and the motion-value hooks (`useMotionValue`, `useScroll`, `useTransform`, `useSpring`, `useAnimate`, `useMotionValueEvent`); motion-dom's animation engine and gesture primitives are reused verbatim.",
|
|
@@ -260,7 +293,7 @@
|
|
|
260
293
|
},
|
|
261
294
|
{
|
|
262
295
|
"name": "@octanejs/nuqs",
|
|
263
|
-
"version": "0.1.
|
|
296
|
+
"version": "0.1.21",
|
|
264
297
|
"category": "AI, data, and routing",
|
|
265
298
|
"upstream": { "package": "nuqs", "version": "2.9.1" },
|
|
266
299
|
"surface": "Full vendored port: the framework-agnostic core (`parsers`/`parseAs*`/`createParser`, `createSerializer`, `createLoader`, `createStandardSchemaV1`, the throttle/debounce update queues, sync emitter and URL encoding) is vendored verbatim from nuqs 2.9.1; the React layer (`useQueryState`, `useQueryStates`, the `useSyncExternalStores` helper and the adapter context) is ported onto octane's hooks — same `useState`/`useEffect`/`useSyncExternalStore` implementation shape as upstream, so re-render and URL-reconciliation behaviour matches nuqs on React. Adapters ported: `@octanejs/nuqs/adapters/react` (`NuqsAdapter`, `enableHistorySync`), `/adapters/custom` (`unstable_createAdapterProvider`), `/adapters/testing` (`NuqsTestingAdapter`, `withNuqsTestingAdapter`). Server surface (`@octanejs/nuqs/server`) exposes `createLoader`/`createSerializer`/parsers/`createStandardSchemaV1`.",
|
|
@@ -275,7 +308,7 @@
|
|
|
275
308
|
},
|
|
276
309
|
{
|
|
277
310
|
"name": "@octanejs/phosphor-icons",
|
|
278
|
-
"version": "0.0.
|
|
311
|
+
"version": "0.0.12",
|
|
279
312
|
"category": "UI and interaction",
|
|
280
313
|
"upstream": { "package": "@phosphor-icons/react", "version": "2.1.10" },
|
|
281
314
|
"surface": "All 1,512 canonical icons from @phosphor-icons/core@2.1.1, including the upstream deprecated Icon-suffixed aliases, six weights, IconContext, IconBase, root exports, and per-icon imports.",
|
|
@@ -289,7 +322,7 @@
|
|
|
289
322
|
},
|
|
290
323
|
{
|
|
291
324
|
"name": "@octanejs/radix",
|
|
292
|
-
"version": "0.1.
|
|
325
|
+
"version": "0.1.31",
|
|
293
326
|
"category": "UI and interaction",
|
|
294
327
|
"upstream": { "package": "radix-ui", "version": "1.6.4" },
|
|
295
328
|
"surface": "Complete against the unified `radix-ui@1.6.4` component surface — all primitives (incl. Dialog, the Menu/DropdownMenu/ContextMenu family, Popover, Tooltip, Select, NavigationMenu, Toast, Menubar, Slider, the form controls, and OneTimePasswordField/PasswordToggleField) plus the composition/state/overlay foundations — verified by a differential suite (same fixtures through octane and the real radix-ui, byte-identical DOM).",
|
|
@@ -302,7 +335,7 @@
|
|
|
302
335
|
},
|
|
303
336
|
{
|
|
304
337
|
"name": "@octanejs/rainbowkit",
|
|
305
|
-
"version": "0.0.
|
|
338
|
+
"version": "0.0.12",
|
|
306
339
|
"category": "Web3",
|
|
307
340
|
"upstream": { "package": "@rainbow-me/rainbowkit", "version": "2.2.11" },
|
|
308
341
|
"surface": "Octane-native RainbowKitProvider, ConnectButton and ConnectButton.Custom, WalletButton, connect/account/chain modal hooks, connector selection, account/chain actions, native accessible dialogs, and light/dark/midnight themes.",
|
|
@@ -318,7 +351,7 @@
|
|
|
318
351
|
},
|
|
319
352
|
{
|
|
320
353
|
"name": "@octanejs/react-error-boundary",
|
|
321
|
-
"version": "0.1.
|
|
354
|
+
"version": "0.1.13",
|
|
322
355
|
"category": "UI and interaction",
|
|
323
356
|
"upstream": { "package": "react-error-boundary", "version": "6.1.2" },
|
|
324
357
|
"surface": "Complete against the published react-error-boundary 6.1.2 function/type surface adapted to Octane: ErrorBoundary, ErrorBoundaryContext, getErrorMessage, fallback variants, onError/onReset callbacks, resetKeys, useErrorBoundary (including error), withErrorBoundary, OnErrorCallback, and UseErrorBoundaryApi.",
|
|
@@ -330,9 +363,25 @@
|
|
|
330
363
|
"ssr": "The explicit server entry renders children without a boundary so descendant errors propagate, matching react-error-boundary 6.1.2.",
|
|
331
364
|
"verified": "2026-07-29"
|
|
332
365
|
},
|
|
366
|
+
{
|
|
367
|
+
"name": "@octanejs/react-map-gl",
|
|
368
|
+
"version": "0.0.4",
|
|
369
|
+
"category": "Data-heavy screens",
|
|
370
|
+
"upstream": { "package": "@vis.gl/react-mapbox", "version": "8.1.2 (b1e46fcf)" },
|
|
371
|
+
"surface": "Complete against the pinned @vis.gl/react-mapbox 8.1.2 public surface — the package react-map-gl/mapbox re-exports: Map (and default), Marker, Popup, Source, Layer, AttributionControl, FullscreenControl, GeolocateControl, NavigationControl, ScaleControl, useControl, MapProvider, useMap, and every published type. The framework-neutral half of upstream (the Mapbox engine, proxy transform, map ref, and six utils) is reused byte-for-byte and validated by upstream's own specs run against both source trees.",
|
|
372
|
+
"divergences": [
|
|
373
|
+
"<Source> delivers its generated id to child layers through context rather than cloneElement, so the id reaches any descendant <Layer> rather than only direct children. It still overrides an explicitly set source, as cloneElement did.",
|
|
374
|
+
"Map, Marker, Popup and GeolocateControl take their ref as an ordinary prop; Octane has no forwardRef. `<Map ref={mapRef} />` is unchanged.",
|
|
375
|
+
"Effect cleanups run on the passive drain after root.unmount() rather than inside it, so the map's WebGL context and worker pool are released one drain later.",
|
|
376
|
+
"Marker picks between its own element and Mapbox's default pin from what its children actually rendered, because a compiled children block cannot be inspected the way React.Children.forEach inspects descriptors. Children that render something, render nothing, or first render after mount all match upstream; a child that stays truthy while rendering nothing forever gets the default pin here and an empty, invisible element upstream.",
|
|
377
|
+
"react-map-gl/mapbox-legacy (mapbox-gl v1) and @vis.gl/react-maplibre are out of scope."
|
|
378
|
+
],
|
|
379
|
+
"ssr": "Supported and tested: Map server-renders its container with the merged style and omits every child, because mapbox-gl is only imported inside an effect. Nothing in the tree reads a browser global on the server. hydrateRoot adopts that container rather than replacing it, and the map is created inside the server's own node once the library resolves.",
|
|
380
|
+
"verified": "2026-08-06"
|
|
381
|
+
},
|
|
333
382
|
{
|
|
334
383
|
"name": "@octanejs/recharts",
|
|
335
|
-
"version": "0.1.
|
|
384
|
+
"version": "0.1.29",
|
|
336
385
|
"category": "Data-heavy screens",
|
|
337
386
|
"upstream": { "package": "recharts", "version": "3.9.2" },
|
|
338
387
|
"surface": "Broad runtime support across cartesian, polar, hierarchical, tooltip, legend, responsive-container, shape, and chart-state surfaces. `Brush` and `Treemap` remain intentionally unsupported.",
|
|
@@ -344,7 +393,7 @@
|
|
|
344
393
|
},
|
|
345
394
|
{
|
|
346
395
|
"name": "@octanejs/redux",
|
|
347
|
-
"version": "0.1.
|
|
396
|
+
"version": "0.1.29",
|
|
348
397
|
"category": "Shared state",
|
|
349
398
|
"upstream": { "package": "react-redux", "version": "9.3.0" },
|
|
350
399
|
"surface": "The hooks + `Provider` surface of react-redux 9.3.0 (`useSelector`, `useDispatch`, `useStore`, and the custom-context factory variants) on octane's `useSyncExternalStore`; works with any Redux 5 / Redux Toolkit store. Export parity is pinned by test.",
|
|
@@ -357,7 +406,7 @@
|
|
|
357
406
|
},
|
|
358
407
|
{
|
|
359
408
|
"name": "@octanejs/redux-toolkit",
|
|
360
|
-
"version": "0.1.
|
|
409
|
+
"version": "0.1.27",
|
|
361
410
|
"category": "Shared state",
|
|
362
411
|
"upstream": { "package": "@reduxjs/toolkit", "version": "2.12.0" },
|
|
363
412
|
"surface": "Complete four-entry-point port: the framework-agnostic Toolkit and RTK Query core are re-exported verbatim; `/query/react` provides generated query, lazy-query, mutation, infinite-query, prefetch hooks and `ApiProvider`; `/react` provides the dynamic-middleware dispatch-hook integration.",
|
|
@@ -370,7 +419,7 @@
|
|
|
370
419
|
},
|
|
371
420
|
{
|
|
372
421
|
"name": "@octanejs/remix-router",
|
|
373
|
-
"version": "0.1.
|
|
422
|
+
"version": "0.1.28",
|
|
374
423
|
"category": "AI, data, and routing",
|
|
375
424
|
"upstream": { "package": "react-router", "version": "8.2.0" },
|
|
376
425
|
"surface": "COMPLETE port (all phases shipped — full export parity, EXPECTED_MISSING is empty): the framework-agnostic router core (lib/router/* + framework-free helpers, ~12k lines) is vendored byte-close and validated by 161 ported upstream router tests plus four focused v8.2 regression pins; the data-mode React layer (createMemoryRouter, RouterProvider incl. the /dom flushSync variant, Outlet, Await, RenderErrorBoundary/errorElement, Link + useLinkClickHandler, and the full read-hook family) and the declarative layer (MemoryRouter, Routes/Route in BOTH children forms — descriptor children walked upstream-style, .tsrx block children via a registration collector — Navigate, createRoutesFromChildren/Elements, the UNSAFE_With*Props wrappers) and the DOM layer (createBrowserRouter/createHashRouter with __staticRouterHydrationData parsing, BrowserRouter/HashRouter/unstable_HistoryRouter, Link + NavLink incl. the isActive/isPending render props, useLinkClickHandler, useSearchParams) and the mutation layer (Form on octane's native delegated submit event, useSubmit incl. JSON encTypes, useFormAction with ?index resolution, useFetcher/useFetchers incl. fetcher.Form/load/submit/reset and shared keys), the guard/scroll layer (useBlocker, unstable_usePrompt, ScrollRestoration/UNSAFE_useScrollRestoration, useBeforeUnload, useViewTransitionState, unstable_useRoute/unstable_useRouterState), static SSR (StaticRouter, StaticRouterProvider, createStaticHandler/createStaticRouter rendering through octane/server — markup byte-identical to react-dom/server after marker stripping, hydration payload identical), and the vendored cookie/session server runtime (createCookie/createSession/createCookieSessionStorage/createMemorySessionStorage) are transcribed onto octane and differential-verified against real react-router. Framework-mode + RSC names (Meta/Links/Scripts, createRequestHandler, UNSAFE_ internals) exist as THROWING STUBS so parity is honest.",
|
|
@@ -386,7 +435,7 @@
|
|
|
386
435
|
},
|
|
387
436
|
{
|
|
388
437
|
"name": "@octanejs/rxjs",
|
|
389
|
-
"version": "0.1.
|
|
438
|
+
"version": "0.1.11",
|
|
390
439
|
"category": "Shared state",
|
|
391
440
|
"upstream": {
|
|
392
441
|
"package": "@react-rxjs/core + @react-rxjs/utils",
|
|
@@ -402,7 +451,7 @@
|
|
|
402
451
|
},
|
|
403
452
|
{
|
|
404
453
|
"name": "@octanejs/shadcn",
|
|
405
|
-
"version": "0.0.
|
|
454
|
+
"version": "0.0.17",
|
|
406
455
|
"category": "UI and interaction",
|
|
407
456
|
"upstream": {
|
|
408
457
|
"package": "shadcn-ui/ui (radix base)",
|
|
@@ -429,7 +478,7 @@
|
|
|
429
478
|
},
|
|
430
479
|
{
|
|
431
480
|
"name": "@octanejs/sonner",
|
|
432
|
-
"version": "0.1.
|
|
481
|
+
"version": "0.1.27",
|
|
433
482
|
"category": "UI and interaction",
|
|
434
483
|
"upstream": { "package": "sonner", "version": "2.0.7" },
|
|
435
484
|
"surface": "Complete against the published `sonner@2.0.7` public surface: `Toaster`, the callable `toast` API and all methods, `useSonner`, promise lifecycle, multiple toaster targeting, stacked layout, themes, styling, focus management, timers, and swipe dismissal.",
|
|
@@ -443,7 +492,7 @@
|
|
|
443
492
|
},
|
|
444
493
|
{
|
|
445
494
|
"name": "@octanejs/streamdown",
|
|
446
|
-
"version": "0.1.
|
|
495
|
+
"version": "0.1.11",
|
|
447
496
|
"category": "Forms and content",
|
|
448
497
|
"upstream": { "package": "streamdown", "version": "2.5.0" },
|
|
449
498
|
"surface": "Complete Streamdown 2.5.0 root runtime and public type surface, plus the official code 1.1.1, math 1.0.2, Mermaid 1.0.2, and CJK 1.0.3 plugins exposed through ./code, ./math, ./mermaid, and ./cjk.",
|
|
@@ -456,7 +505,7 @@
|
|
|
456
505
|
},
|
|
457
506
|
{
|
|
458
507
|
"name": "@octanejs/styled-components",
|
|
459
|
-
"version": "0.1.
|
|
508
|
+
"version": "0.1.24",
|
|
460
509
|
"category": "Styling, tests, and devtools",
|
|
461
510
|
"upstream": { "package": "styled-components", "version": "6.4.3" },
|
|
462
511
|
"surface": "Full v6 web API, ported from the upstream 6.4.3 sources: `styled` with every HTML/SVG tag shortcut, `.attrs`/`.withConfig` chaining, `css`, `keyframes`, `createGlobalStyle`, `createTheme`, `ThemeProvider`/`ThemeContext`/`ThemeConsumer`/`useTheme`/`withTheme`, `StyleSheetManager`/`StyleSheetContext`/`StyleSheetConsumer` (targets, namespaces, vendor prefixing, stylis plugins, `shouldForwardProp`), `ServerStyleSheet`, `isStyledComponent`, `version`, and `__PRIVATE__`. Component selectors, folding (`styled(Styled)`), transient `$` props, `as`/`forwardedAs`, and the grouped CSSOM sheet engine (with upstream `data-styled` rehydration) all behave as upstream. The React Native surface and the RSC-only `stylisPluginRSC` are not ported.",
|
|
@@ -475,7 +524,7 @@
|
|
|
475
524
|
},
|
|
476
525
|
{
|
|
477
526
|
"name": "@octanejs/stylex",
|
|
478
|
-
"version": "0.1.
|
|
527
|
+
"version": "0.1.31",
|
|
479
528
|
"category": "Styling, tests, and devtools",
|
|
480
529
|
"upstream": { "package": "@stylexjs/stylex", "version": "0.19.0" },
|
|
481
530
|
"surface": "Full compile-time integration: re-exports the StyleX runtime API (`create`, `props`, `attrs`, `keyframes`, `defineVars`, `createTheme`) and registers as an import source; the `/vite` plugin runs the StyleX compiler over octane's compiled output and emits one static atomic stylesheet (`virtual:stylex.css`) with zero StyleX runtime in the bundle.",
|
|
@@ -488,7 +537,7 @@
|
|
|
488
537
|
},
|
|
489
538
|
{
|
|
490
539
|
"name": "@octanejs/tanstack-ai",
|
|
491
|
-
"version": "0.0.
|
|
540
|
+
"version": "0.0.26",
|
|
492
541
|
"category": "AI, data, and routing",
|
|
493
542
|
"upstream": { "package": "@tanstack/ai-react", "version": "0.17.0" },
|
|
494
543
|
"surface": "Ports the @tanstack/ai-react 0.17.0 hook surface (useChat, useRealtimeChat, useGeneration, useGenerateImage/Audio/Speech/Video, useTranscription, useSummarize, useAudioRecorder, useMcpAppBridge) while reusing @tanstack/ai 0.41.0 and @tanstack/ai-client 0.21.0 unchanged and mirroring all 30 @tanstack/ai-client convenience re-exports from the upstream index.",
|
|
@@ -507,7 +556,7 @@
|
|
|
507
556
|
},
|
|
508
557
|
{
|
|
509
558
|
"name": "@octanejs/tanstack-devtools",
|
|
510
|
-
"version": "0.0.
|
|
559
|
+
"version": "0.0.26",
|
|
511
560
|
"category": "Styling, tests, and devtools",
|
|
512
561
|
"upstream": { "package": "@tanstack/react-devtools", "version": "0.10.7" },
|
|
513
562
|
"surface": "Ports the @tanstack/react-devtools 0.10.7 public surface (the `TanStackDevtools` component plus its plugin/init types) onto Octane while reusing the framework-agnostic `@tanstack/devtools` 0.12.5 core (`TanStackDevtoolsCore`) unchanged. Plugin, title, and custom-trigger content authored as Octane elements is portaled into the containers the core creates.",
|
|
@@ -522,7 +571,7 @@
|
|
|
522
571
|
},
|
|
523
572
|
{
|
|
524
573
|
"name": "@octanejs/tanstack-form",
|
|
525
|
-
"version": "0.0.
|
|
574
|
+
"version": "0.0.26",
|
|
526
575
|
"category": "Forms and content",
|
|
527
576
|
"upstream": { "package": "@tanstack/react-form", "version": "1.33.2" },
|
|
528
577
|
"surface": "Ports the complete @tanstack/react-form 1.33.2 adapter surface (`useForm`, `useField`, form and field groups, hook contexts and component composition) while re-exporting @tanstack/form-core 1.33.2 unchanged and using @octanejs/tanstack-store for subscriptions.",
|
|
@@ -536,7 +585,7 @@
|
|
|
536
585
|
},
|
|
537
586
|
{
|
|
538
587
|
"name": "@octanejs/tanstack-hotkeys",
|
|
539
|
-
"version": "0.0.
|
|
588
|
+
"version": "0.0.21",
|
|
540
589
|
"category": "UI and interaction",
|
|
541
590
|
"upstream": { "package": "@tanstack/react-hotkeys", "version": "0.10.0" },
|
|
542
591
|
"surface": "Complete: the full upstream hook surface (`useHotkey`, `useHotkeys`, `useHeldKeys`, `useHeldKeyCodes`, `useKeyHold`, `useHotkeySequence`, `useHotkeySequences`, `useHotkeyRecorder`, `useHotkeySequenceRecorder`, `useHotkeyRegistrations`) plus `HotkeysProvider`/`useHotkeysContext`/`useDefaultHotkeysOptions`, re-exporting the framework-agnostic `@tanstack/hotkeys@0.8.0` core unchanged; store subscriptions go through `@octanejs/tanstack-store`.",
|
|
@@ -548,7 +597,7 @@
|
|
|
548
597
|
},
|
|
549
598
|
{
|
|
550
599
|
"name": "@octanejs/tanstack-pacer",
|
|
551
|
-
"version": "0.0.
|
|
600
|
+
"version": "0.0.21",
|
|
552
601
|
"category": "UI and interaction",
|
|
553
602
|
"upstream": { "package": "@tanstack/react-pacer", "version": "0.22.1" },
|
|
554
603
|
"surface": "Complete: every upstream hook family — debouncer (`useDebouncer`, `useDebouncedState`, `useDebouncedValue`, `useDebouncedCallback`), throttler, rate-limiter, queuer, batcher, and their async variants (async-debouncer, async-throttler, async-rate-limiter, async-queuer, async-batcher) — plus `PacerProvider`/`usePacerContext`/`useDefaultPacerOptions`, the per-instance `Subscribe` render-prop component, and the upstream subpath exports (`/debouncer`, `/async-retryer`, `/types`, `/utils`, ...), re-exporting the framework-agnostic `@tanstack/pacer@0.21.1` core unchanged.",
|
|
@@ -560,7 +609,7 @@
|
|
|
560
609
|
},
|
|
561
610
|
{
|
|
562
611
|
"name": "@octanejs/tanstack-query",
|
|
563
|
-
"version": "0.1.
|
|
612
|
+
"version": "0.1.31",
|
|
564
613
|
"category": "AI, data, and routing",
|
|
565
614
|
"upstream": { "package": "@tanstack/react-query", "version": "5.101.3" },
|
|
566
615
|
"surface": "Complete: 58/58 runtime exports plus the full TypeScript surface; the export surface is byte-identical to upstream in both directions (locked by test), and `@tanstack/query-core` is re-exported verbatim.",
|
|
@@ -572,7 +621,7 @@
|
|
|
572
621
|
},
|
|
573
622
|
{
|
|
574
623
|
"name": "@octanejs/tanstack-router",
|
|
575
|
-
"version": "0.1.
|
|
624
|
+
"version": "0.1.31",
|
|
576
625
|
"category": "AI, data, and routing",
|
|
577
626
|
"upstream": { "package": "@tanstack/react-router", "version": "1.170.18" },
|
|
578
627
|
"surface": "Octane's TanStack Router binding: typed route factories and hooks, the full Match pipeline and lifecycle, file routes with TSRX-aware generator integration, full Link navigation/preloading/masking behavior, blocking, Await/deferred hydration, scroll restoration, lazy routes, not-found handling, document/head assets, and client/server SSR entries.",
|
|
@@ -586,7 +635,7 @@
|
|
|
586
635
|
},
|
|
587
636
|
{
|
|
588
637
|
"name": "@octanejs/tanstack-router-ssr-query",
|
|
589
|
-
"version": "0.0.
|
|
638
|
+
"version": "0.0.21",
|
|
590
639
|
"category": "AI, data, and routing",
|
|
591
640
|
"upstream": { "package": "@tanstack/react-router-ssr-query", "version": "1.167.1" },
|
|
592
641
|
"surface": "Complete: `setupRouterSsrQueryIntegration` (the package's only export) delegating to `@tanstack/router-ssr-query-core@1.169.1`, with the QueryClientProvider Wrap composition on Octane.",
|
|
@@ -596,7 +645,7 @@
|
|
|
596
645
|
},
|
|
597
646
|
{
|
|
598
647
|
"name": "@octanejs/tanstack-store",
|
|
599
|
-
"version": "0.0.
|
|
648
|
+
"version": "0.0.26",
|
|
600
649
|
"category": "Shared state",
|
|
601
650
|
"upstream": { "package": "@tanstack/react-store", "version": "0.11.0" },
|
|
602
651
|
"surface": "Re-exports `@tanstack/store@0.11.0` unchanged and implements the stable React binding surface (`useSelector`, `useAtom`, `useCreateAtom`, `useCreateStore`, `createStoreContext`, and deprecated `useStore`) on Octane hooks.",
|
|
@@ -608,7 +657,7 @@
|
|
|
608
657
|
},
|
|
609
658
|
{
|
|
610
659
|
"name": "@octanejs/tanstack-table",
|
|
611
|
-
"version": "0.1.
|
|
660
|
+
"version": "0.1.29",
|
|
612
661
|
"category": "Data-heavy screens",
|
|
613
662
|
"upstream": { "package": "@tanstack/react-table", "version": "9.0.0-beta.58" },
|
|
614
663
|
"surface": "Complete port of the v9 adapter: the framework-agnostic `@tanstack/table-core` (constructTable + every tree-shakeable feature and row model) is reused verbatim, and the adapter — `useTable`, `Subscribe`, `flexRender`/`FlexRender`, `createTableHook`, `createTableHookContexts` — is transcribed onto octane hooks. Table state lives in TanStack Store atoms via the `coreReactivityFeature` bindings, and `useSelector` drives re-renders from the selected slice. Every store primitive (hooks, `createAtom`, `batch`, `shallow`, and the atom/store types) is imported from @octanejs/tanstack-store, which re-exports all of @tanstack/store — the binding takes no direct dependency on the store core, so there is only one path to it and atom identity cannot be split across duplicate copies.",
|
|
@@ -621,7 +670,7 @@
|
|
|
621
670
|
},
|
|
622
671
|
{
|
|
623
672
|
"name": "@octanejs/tanstack-virtual",
|
|
624
|
-
"version": "0.1.
|
|
673
|
+
"version": "0.1.29",
|
|
625
674
|
"category": "Data-heavy screens",
|
|
626
675
|
"upstream": { "package": "@tanstack/react-virtual", "version": "3.14.5" },
|
|
627
676
|
"surface": "Complete 1:1 port: the framework-agnostic `@tanstack/virtual-core` (Virtualizer + observers + windowing math) is reused verbatim; the React adapter (`useVirtualizer`, `useWindowVirtualizer`, incl. `useFlushSync` and the experimental `directDomUpdates` surface) is transcribed onto octane hooks, preserving upstream's force-update + flushSync-on-sync-scroll wiring and layout-effect lifecycle.",
|
|
@@ -633,7 +682,7 @@
|
|
|
633
682
|
},
|
|
634
683
|
{
|
|
635
684
|
"name": "@octanejs/tauri",
|
|
636
|
-
"version": "0.0.
|
|
685
|
+
"version": "0.0.15",
|
|
637
686
|
"category": "Desktop",
|
|
638
687
|
"upstream": { "package": "@tauri-apps/api", "version": "2.11.1" },
|
|
639
688
|
"surface": "Octane hooks over the framework-neutral Tauri IPC surface: useInvoke (suspending command), useInvokeState (pending/success/error with refetch), and useTauriEvent (event subscription with lifecycle-safe teardown). The rest of @tauri-apps/api — window, webview, menu, tray, path, dpi, image, and the plugin packages — is already framework-neutral and is imported directly rather than re-exported here.",
|
|
@@ -651,7 +700,7 @@
|
|
|
651
700
|
},
|
|
652
701
|
{
|
|
653
702
|
"name": "@octanejs/testing-library",
|
|
654
|
-
"version": "0.1.
|
|
703
|
+
"version": "0.1.29",
|
|
655
704
|
"category": "Styling, tests, and devtools",
|
|
656
705
|
"upstream": { "package": "@testing-library/react", "version": "unpinned" },
|
|
657
706
|
"surface": "`render`/`rerender`/`cleanup`/`renderHook` + `act` over the verbatim `@testing-library/dom` (every query, `screen`, `within`, `waitFor`, `fireEvent`, `prettyDOM`, `configure`), with commit timing wired to octane's scheduler via the dom-library's `eventWrapper`/`asyncWrapper` config.",
|
|
@@ -664,7 +713,7 @@
|
|
|
664
713
|
},
|
|
665
714
|
{
|
|
666
715
|
"name": "@octanejs/three",
|
|
667
|
-
"version": "0.1.
|
|
716
|
+
"version": "0.1.25",
|
|
668
717
|
"category": "Web 3D",
|
|
669
718
|
"upstream": { "package": "@react-three/fiber", "version": "9.6.1 (2a528745)" },
|
|
670
719
|
"surface": "Technical-preview Milestones 0–10 surface: renderer configuration and the DOM Canvas boundary, compiler ABI and renderer-local Three intrinsic types, catalogue and both extend forms, primitive/args construction, Three prop application, attachment, ordered placement/recreation, retained visibility, lifecycle/ref delivery, ownership-aware disposal, promise-returning HTMLCanvasElement and OffscreenCanvas roots, Octane act/flushSync scheduling, callback-aware unmountComponentAtNode, callable root state, scene/camera/raycaster and resize/DPR/viewport configuration, shadows/colors, one shared frame loop, controlled WebXR loop handoff, context-restore invalidation, compatible/reconstructing HMR, global effects, useStore/useThree/useFrame/useGraph and managed-instance helpers, the ray/pointer event system with DOM sources and custom managers, a keyed useLoader cache with preload/clear and GLTF graph augmentation, retained Suspense/Activity behavior, client Three-to-DOM pending/error projection, same-renderer createPortal targets with state/event enclaves and physical Three event bubbling, client-only Canvas shell streaming and production Vite/Rsbuild hydration adoption with the matching raw Rspack graph split, the explicit-target low-level DOMRegion boundary, a deterministic testing harness, an asynchronously acknowledged structured-clone transport proof, a checked public API/subpath matrix, Three r156/current compatibility lanes, a packed external consumer, real WebGL failure/recovery coverage, and semantic-checksummed renderer and shipped-size benchmarks.",
|
|
@@ -685,7 +734,7 @@
|
|
|
685
734
|
},
|
|
686
735
|
{
|
|
687
736
|
"name": "@octanejs/tiptap",
|
|
688
|
-
"version": "0.0.
|
|
737
|
+
"version": "0.0.26",
|
|
689
738
|
"category": "Forms and content",
|
|
690
739
|
"upstream": { "package": "@tiptap/react", "version": "3.28.0" },
|
|
691
740
|
"surface": "Complete @tiptap/react 3.28.0 adapter surface across the root and ./menus entries: @tiptap/core re-exports, editor hooks and contexts, the EditorContent portal bridge, compound Tiptap API, ReactRenderer, custom NodeView/MarkView renderers and helpers, BubbleMenu, and FloatingMenu.",
|
|
@@ -702,7 +751,7 @@
|
|
|
702
751
|
},
|
|
703
752
|
{
|
|
704
753
|
"name": "@octanejs/usehooks-ts",
|
|
705
|
-
"version": "0.0.
|
|
754
|
+
"version": "0.0.13",
|
|
706
755
|
"category": "UI and interaction",
|
|
707
756
|
"upstream": {
|
|
708
757
|
"package": "usehooks-ts",
|
|
@@ -720,7 +769,7 @@
|
|
|
720
769
|
},
|
|
721
770
|
{
|
|
722
771
|
"name": "@octanejs/valtio",
|
|
723
|
-
"version": "0.1.
|
|
772
|
+
"version": "0.1.15",
|
|
724
773
|
"category": "Shared state",
|
|
725
774
|
"upstream": { "package": "valtio", "version": "2.3.2" },
|
|
726
775
|
"surface": "The framework-agnostic `valtio/vanilla` core and `valtio/vanilla/utils` are re-exported verbatim; `useSnapshot` and the `useProxy` utility are ported to Octane.",
|
|
@@ -732,7 +781,7 @@
|
|
|
732
781
|
},
|
|
733
782
|
{
|
|
734
783
|
"name": "@octanejs/visx",
|
|
735
|
-
"version": "0.1.
|
|
784
|
+
"version": "0.1.26",
|
|
736
785
|
"category": "Data-heavy screens",
|
|
737
786
|
"upstream": { "package": "@visx/visx", "version": "4.0.0 + master@485c035" },
|
|
738
787
|
"surface": "Complete current Visx 4.x web runtime surface: the exact 35-namespace aggregate, all 40 feature entry points, and the eight public a11y/react, a11y/server, axis/react, scale/react, shape/react, theme/react, tooltip/floating, and voronoi/react subpaths. Released-only packages chord, delaunay, react-spring, sankey, and stats remain directly importable exactly as upstream specifies.",
|
|
@@ -748,7 +797,7 @@
|
|
|
748
797
|
},
|
|
749
798
|
{
|
|
750
799
|
"name": "@octanejs/wagmi",
|
|
751
|
-
"version": "0.0.
|
|
800
|
+
"version": "0.0.12",
|
|
752
801
|
"category": "Web3",
|
|
753
802
|
"upstream": { "package": "wagmi", "version": "3.7.4" },
|
|
754
803
|
"surface": "WagmiProvider and createConfig over @wagmi/core 3.6.4, with config, connection, connect, disconnect, switch-connection, switch-chain, connectors, connections, chains, balance, contract read/simulate/write, transaction send/wait, and message-signing hooks.",
|
|
@@ -764,7 +813,7 @@
|
|
|
764
813
|
},
|
|
765
814
|
{
|
|
766
815
|
"name": "@octanejs/zustand",
|
|
767
|
-
"version": "0.1.
|
|
816
|
+
"version": "0.1.31",
|
|
768
817
|
"category": "Shared state",
|
|
769
818
|
"upstream": { "package": "zustand", "version": "5.0.14" },
|
|
770
819
|
"surface": "Complete 1:1 port: the framework-agnostic vanilla store is reused verbatim; `create`/`useStore`, `shallow`/`useShallow`, the traditional equality-fn variants, and all middleware (persist, devtools, subscribeWithSelector, combine, redux).",
|
|
@@ -781,6 +830,7 @@
|
|
|
781
830
|
"@dnd-kit/react": "@octanejs/dnd-kit",
|
|
782
831
|
"@floating-ui/react": "@octanejs/floating-ui",
|
|
783
832
|
"@lexical/react": "@octanejs/lexical",
|
|
833
|
+
"@livestore/react": "@octanejs/livestore",
|
|
784
834
|
"@mantine/hooks": "@octanejs/mantine-hooks",
|
|
785
835
|
"@mdx-js/react": "@octanejs/mdx",
|
|
786
836
|
"@phosphor-icons/react": "@octanejs/phosphor-icons",
|
|
@@ -807,6 +857,7 @@
|
|
|
807
857
|
"@tanstack/react-virtual": "@octanejs/tanstack-virtual",
|
|
808
858
|
"@testing-library/react": "@octanejs/testing-library",
|
|
809
859
|
"@tiptap/react": "@octanejs/tiptap",
|
|
860
|
+
"@vis.gl/react-mapbox": "@octanejs/react-map-gl",
|
|
810
861
|
"@visx/a11y": "@octanejs/visx",
|
|
811
862
|
"@visx/a11y/react": "@octanejs/visx",
|
|
812
863
|
"@visx/a11y/server": "@octanejs/visx",
|
|
@@ -856,6 +907,7 @@
|
|
|
856
907
|
"@visx/wordcloud": "@octanejs/visx",
|
|
857
908
|
"@visx/xychart": "@octanejs/visx",
|
|
858
909
|
"@visx/zoom": "@octanejs/visx",
|
|
910
|
+
"animejs": "@octanejs/animejs",
|
|
859
911
|
"cmdk": "@octanejs/cmdk",
|
|
860
912
|
"dexie-react-hooks": "@octanejs/dexie",
|
|
861
913
|
"framer-motion": "@octanejs/motion",
|
|
@@ -871,6 +923,8 @@
|
|
|
871
923
|
"react-error-boundary": "@octanejs/react-error-boundary",
|
|
872
924
|
"react-hook-form": "@octanejs/hook-form",
|
|
873
925
|
"react-i18next": "@octanejs/i18next",
|
|
926
|
+
"react-map-gl": "@octanejs/react-map-gl",
|
|
927
|
+
"react-map-gl/mapbox": "@octanejs/react-map-gl",
|
|
874
928
|
"react-redux": "@octanejs/redux",
|
|
875
929
|
"react-router": "@octanejs/remix-router",
|
|
876
930
|
"react-router-dom": "@octanejs/remix-router",
|
package/src/kernel/install.js
CHANGED
|
@@ -8,6 +8,33 @@ const MANAGERS = {
|
|
|
8
8
|
bun: { add: ['add'], dev: '-d' },
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Dependency install scripts pnpm should be told to run.
|
|
13
|
+
*
|
|
14
|
+
* pnpm blocks them until the project records a decision, and since 11.0 an
|
|
15
|
+
* undecided script fails the whole install rather than warning: the packages
|
|
16
|
+
* land on disk and pnpm still exits non-zero. A scaffold that says nothing
|
|
17
|
+
* therefore stops partway through, with the dependencies installed and the dev
|
|
18
|
+
* dependencies missing, which leaves an app whose `dev` script cannot start.
|
|
19
|
+
*
|
|
20
|
+
* esbuild is the one the generated projects cannot run without: its install
|
|
21
|
+
* script is how vite's platform binary arrives. Only packages named here are
|
|
22
|
+
* approved, so a build script arriving through some other dependency stays the
|
|
23
|
+
* user's call to make.
|
|
24
|
+
*
|
|
25
|
+
* npm and yarn run install scripts by default and need none of this. bun blocks
|
|
26
|
+
* them like pnpm but exits zero, so it never breaks the scaffold; teaching the
|
|
27
|
+
* templates `trustedDependencies` is a separate change.
|
|
28
|
+
*/
|
|
29
|
+
export const PNPM_ALLOWED_BUILDS = ['esbuild'];
|
|
30
|
+
|
|
31
|
+
/** What pnpm calls the failure above. */
|
|
32
|
+
const IGNORED_BUILDS = 'ERR_PNPM_IGNORED_BUILDS';
|
|
33
|
+
|
|
34
|
+
/** Said once per run: the build script is the same one every install trips on. */
|
|
35
|
+
const APPROVE_BUILDS =
|
|
36
|
+
'pnpm blocked a dependency install script. Run `pnpm approve-builds` to decide on it.';
|
|
37
|
+
|
|
11
38
|
/**
|
|
12
39
|
* The managers this CLI knows how to drive. Derived rather than written out, so
|
|
13
40
|
* that a flag can never offer a manager `installCommand` would silently answer
|
|
@@ -19,12 +46,18 @@ export const PACKAGE_MANAGERS = Object.keys(MANAGERS);
|
|
|
19
46
|
* @param {import('./project.js').Project} project
|
|
20
47
|
* @param {string[]} names
|
|
21
48
|
* @param {boolean} dev
|
|
49
|
+
* @param {{ allowBuilds?: readonly string[] }} [options]
|
|
22
50
|
* @returns {{ manager: string, args: string[] }}
|
|
23
51
|
*/
|
|
24
|
-
export function installCommand(project, names, dev = false) {
|
|
52
|
+
export function installCommand(project, names, dev = false, { allowBuilds = [] } = {}) {
|
|
25
53
|
const manager = project.packageManager ?? 'npm';
|
|
26
54
|
const recipe = MANAGERS[/** @type {keyof typeof MANAGERS} */ (manager)] ?? MANAGERS.npm;
|
|
27
|
-
|
|
55
|
+
// `--allow-build` is pnpm's spelling, and npm would read it as a package name.
|
|
56
|
+
const approvals = manager === 'pnpm' ? allowBuilds.map((name) => `--allow-build=${name}`) : [];
|
|
57
|
+
return {
|
|
58
|
+
manager,
|
|
59
|
+
args: [...recipe.add, ...approvals, ...(dev ? [recipe.dev] : []), ...names],
|
|
60
|
+
};
|
|
28
61
|
}
|
|
29
62
|
|
|
30
63
|
/**
|
|
@@ -34,17 +67,42 @@ export function installCommand(project, names, dev = false) {
|
|
|
34
67
|
* @param {import('./context.js').Ctx} ctx
|
|
35
68
|
* @param {import('./project.js').Project} project
|
|
36
69
|
* @param {string[]} names
|
|
37
|
-
* @param {{ dev?: boolean }} [options]
|
|
38
|
-
* @returns {Promise<string>} the command that
|
|
70
|
+
* @param {{ dev?: boolean, allowBuilds?: readonly string[] }} [options]
|
|
71
|
+
* @returns {Promise<{ command: string, warnings: string[] }>} the command that
|
|
72
|
+
* ran, and anything the user has to settle themselves
|
|
39
73
|
*/
|
|
40
|
-
export async function installPackages(
|
|
41
|
-
|
|
42
|
-
|
|
74
|
+
export async function installPackages(
|
|
75
|
+
ctx,
|
|
76
|
+
project,
|
|
77
|
+
names,
|
|
78
|
+
{ dev = false, allowBuilds: approved = [] } = {},
|
|
79
|
+
) {
|
|
80
|
+
const run = async (/** @type {readonly string[]} */ allowBuilds) => {
|
|
81
|
+
const { manager, args } = installCommand(project, names, dev, { allowBuilds });
|
|
82
|
+
const result = await ctx.exec.run(manager, args, { cwd: project.root });
|
|
83
|
+
return { result, command: `${manager} ${args.join(' ')}` };
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
let { result, command } = await run(approved);
|
|
87
|
+
let output = `${result.stdout}\n${result.stderr}`;
|
|
88
|
+
|
|
89
|
+
// `--allow-build` landed in pnpm 10.4. Older pnpm rejects the flag instead of
|
|
90
|
+
// installing, and asking it for its version first would cost a process on
|
|
91
|
+
// every run to spare one retry on almost none of them.
|
|
92
|
+
if (result.code !== 0 && /Unknown option.*allow-build/i.test(output)) {
|
|
93
|
+
({ result, command } = await run([]));
|
|
94
|
+
output = `${result.stdout}\n${result.stderr}`;
|
|
95
|
+
}
|
|
43
96
|
|
|
44
97
|
if (result.code !== 0) {
|
|
45
|
-
|
|
98
|
+
// A blocked build script is reported by failing after the packages are
|
|
99
|
+
// already installed. Carrying on beats aborting: the install did its job,
|
|
100
|
+
// and stopping here would skip the rest of the setup over a decision that
|
|
101
|
+
// is the user's to make.
|
|
102
|
+
if (output.includes(IGNORED_BUILDS)) return { command, warnings: [APPROVE_BUILDS] };
|
|
103
|
+
throw new CliError(`\`${command}\` failed.`, {
|
|
46
104
|
hint: (result.stderr || result.stdout).trim() || 'Install the packages by hand.',
|
|
47
105
|
});
|
|
48
106
|
}
|
|
49
|
-
return
|
|
107
|
+
return { command, warnings: [] };
|
|
50
108
|
}
|