create-octane-xplat 0.7.3 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -8
- package/index.mjs +112 -14
- package/package.json +15 -8
- package/scaffold.mjs +531 -0
- package/template/.agents/skills/xplat/SKILL.md +109 -40
- package/template/.agents/skills/xplat/references/components.md +149 -96
- package/template/.agents/skills/xplat/references/navigation.md +81 -31
- package/template/.agents/skills/xplat/references/platform.md +74 -35
- package/template/.agents/skills/xplat/references/styling.md +80 -27
- package/template/AGENTS.md +1 -1
- package/template/package.json +11 -9
- package/template/pnpm-workspace.yaml +66 -33
- package/template/src/App.tsrx +17 -8
- package/template/src/process.d.ts +7 -0
- package/template/src/style.css +24 -6
- package/template/tsconfig.json +1 -1
- package/template/vite.config.native.mts +3 -2
- package/template/vite.config.ts +5 -3
- package/template/App_Resources/iOS/src/OctaneShaders.metal +0 -128
- package/template/App_Resources/iOS/src/ShaderEffectRegistration.swift +0 -31
- package/template/patches/@nativescript-community__octane@0.2.1.patch +0 -16
- package/template/patches/@nativescript-community__vite-octane@0.2.1.patch +0 -41
- package/template/patches/@nativescript__core@9.1.2.patch +0 -794
- package/template/patches/@nativescript__core@9.1.3-next.2.patch +0 -428
- package/template/patches/@nativescript__vite@8.0.11.patch +0 -569
- package/template/patches/@nativescript__vite@8.0.13.patch +0 -233
- package/template/patches/@tsrx__typescript-plugin@0.4.11.patch +0 -11
- package/template/patches/css@3.0.0.patch +0 -52
- package/template/patches/octane@0.6.3.patch +0 -1149
- /package/template/src/{index.ts → main.ts} +0 -0
|
@@ -1,45 +1,84 @@
|
|
|
1
|
-
# Platform services
|
|
1
|
+
# Platform services and platform files
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use `@octane-xplat/platform` for common device services such as storage,
|
|
4
|
+
clipboard, permissions, connectivity, app lifecycle, URLs, and screen size.
|
|
5
|
+
Clipboard operations can fail or be unavailable; show a useful result.
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
links, clipboard, `secureStorage`, haptics, notifications, `announce`,
|
|
10
|
-
`systemBars`, geolocation, permissions, media, files, share, `openUrl`,
|
|
11
|
-
`openSettings`, biometrics.
|
|
7
|
+
```tsrx
|
|
8
|
+
import { useState } from 'octane'
|
|
9
|
+
import { clipboard } from '@octane-xplat/platform'
|
|
10
|
+
import { Pressable, Text } from '@octane-xplat/ui'
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
export function CopyTrip() {
|
|
13
|
+
const [message, setMessage] = useState('Copy trip link')
|
|
14
|
+
return <Pressable onPress={async () => {
|
|
15
|
+
const copied = await clipboard.writeText('https://example.com/trips/42')
|
|
16
|
+
setMessage(copied ? 'Copied' : 'Copy unavailable')
|
|
17
|
+
}}><Text>{message}</Text></Pressable>
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Features with additional native dependencies live in separate packages:
|
|
22
|
+
`@octane-xplat/share`, `files`, `media`, `biometrics`, `geolocation`,
|
|
23
|
+
`notifications`, `secure-storage`, and `haptics`. Install the package for the
|
|
24
|
+
feature you need. Biometrics, for example, reports `unsupported` on web;
|
|
25
|
+
check permission and availability before trying to verify someone.
|
|
16
26
|
|
|
17
|
-
|
|
27
|
+
```tsrx
|
|
28
|
+
import { useState } from 'octane'
|
|
29
|
+
import { biometrics } from '@octane-xplat/biometrics'
|
|
30
|
+
import { Pressable, Text } from '@octane-xplat/ui'
|
|
31
|
+
|
|
32
|
+
export function UnlockTrip() {
|
|
33
|
+
const [message, setMessage] = useState('Unlock trip')
|
|
34
|
+
return <Pressable onPress={async () => {
|
|
35
|
+
const status = await biometrics.ensure()
|
|
36
|
+
if (status !== 'granted' || !biometrics.impl) {
|
|
37
|
+
setMessage('Use your password instead')
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
const verified = await biometrics.impl.verify('Unlock your trip')
|
|
41
|
+
setMessage(verified ? 'Unlocked' : 'Try again')
|
|
42
|
+
}}><Text>{message}</Text></Pressable>
|
|
43
|
+
}
|
|
44
|
+
```
|
|
18
45
|
|
|
19
|
-
|
|
20
|
-
|
|
46
|
+
## Write a platform file when behavior differs
|
|
47
|
+
|
|
48
|
+
Split the file when a feature needs browser or OS APIs. Import the component
|
|
49
|
+
without a suffix; the bundler selects the matching implementation.
|
|
21
50
|
|
|
22
51
|
```text
|
|
23
|
-
src/parts/Scanner.tsrx
|
|
24
|
-
src/parts/Scanner.web.tsrx browser implementation (camera via getUserMedia)
|
|
52
|
+
src/parts/Scanner.web.tsrx browser implementation
|
|
25
53
|
src/parts/Scanner.mobile.tsrx shared iOS/Android implementation
|
|
26
|
-
src/parts/Scanner.ios.tsrx iOS
|
|
54
|
+
src/parts/Scanner.ios.tsrx iOS override
|
|
55
|
+
src/parts/Scanner.tsrx native default
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```tsrx
|
|
59
|
+
import { Scanner } from './parts/Scanner'
|
|
60
|
+
|
|
61
|
+
export function ScanScreen() { return <Scanner /> }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Native JSX files start with the NativeScript pragma on line 1. Import native
|
|
65
|
+
APIs from `@nativescript/core`, and read app lifecycle state inside the call
|
|
66
|
+
rather than during module initialization. This example belongs in
|
|
67
|
+
`Status.mobile.tsrx`:
|
|
68
|
+
|
|
69
|
+
```tsrx
|
|
70
|
+
/** @jsxImportSource @nativescript-community/octane */
|
|
71
|
+
import { Application } from '@nativescript/core'
|
|
72
|
+
import { Pressable, Text } from '@octane-xplat/ui'
|
|
73
|
+
|
|
74
|
+
export function Status() {
|
|
75
|
+
return <Pressable onPress={() => console.log(Application.hasLaunched())}>
|
|
76
|
+
<Text>Check app status</Text>
|
|
77
|
+
</Pressable>
|
|
78
|
+
}
|
|
27
79
|
```
|
|
28
80
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Leaf rules:
|
|
34
|
-
|
|
35
|
-
- Inside `.web.*`, DOM APIs are expected; NativeScript imports belong in
|
|
36
|
-
`.mobile.*`, `.ios.*`, `.android.*`, or the unsuffixed native default. If
|
|
37
|
-
browser code imports that default, add a `.web.*` sibling.
|
|
38
|
-
- Never read app-level NativeScript globals (`Application.android.*`)
|
|
39
|
-
at module top — read them inside the call. Top-level reads crash cold start
|
|
40
|
-
before the app exists.
|
|
41
|
-
- Native-specific `.tsrx` files containing JSX start with
|
|
42
|
-
`/** @jsxImportSource @nativescript-community/octane */` on line 1.
|
|
43
|
-
- Deep imports under `@nativescript/core/ui/*` bundle as a second module
|
|
44
|
-
instance — import from `@nativescript/core` only.
|
|
45
|
-
- `console.debug` doesn't exist on device — use `console.log`.
|
|
81
|
+
Keep browser globals and DOM events in `.web.*` files. Do not import a second
|
|
82
|
+
renderer or deep-import NativeScript UI modules. Use `console.log` for device
|
|
83
|
+
logging. See the [platform services guide](https://octane-xplat.goddardai.org/platform-services)
|
|
84
|
+
when choosing a service or fallback.
|
|
@@ -1,42 +1,95 @@
|
|
|
1
1
|
# Styling
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use classes for static styling and inline style objects for values that change
|
|
4
|
+
while the app runs. Put the CSS in `src/style.css` and the component in a
|
|
5
|
+
`.tsrx` file.
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
-
|
|
7
|
-
|
|
7
|
+
```css
|
|
8
|
+
.trip-card {
|
|
9
|
+
padding: 16px;
|
|
10
|
+
border-radius: 12px;
|
|
11
|
+
}
|
|
12
|
+
```
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
```tsrx
|
|
15
|
+
import { View, Text } from '@octane-xplat/ui'
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
export function TripCard(props: { opacity: number }) {
|
|
18
|
+
return <View className="trip-card" style={{ opacity: props.opacity }}>
|
|
19
|
+
<Text>Your next adventure</Text>
|
|
20
|
+
</View>
|
|
21
|
+
}
|
|
22
|
+
```
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
## Shared CSS
|
|
18
25
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
Shared CSS compiles for web and native. Prefer flex layouts, padding, and
|
|
27
|
+
supported transforms. The native build warns when it drops declarations such
|
|
28
|
+
as `position: fixed`, `margin: auto`, or `box-shadow`; resolve the warning
|
|
29
|
+
before depending on that style.
|
|
30
|
+
|
|
31
|
+
```css
|
|
32
|
+
.trip-card {
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
padding: 16px;
|
|
36
|
+
}
|
|
37
|
+
.trip-actions {
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: row;
|
|
40
|
+
justify-content: center;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
24
43
|
|
|
25
44
|
## Tokens and dark mode
|
|
26
45
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
46
|
+
The starter imports the framework's tokens. They provide shared layout rules; the starter
|
|
47
|
+
defines its app palette in `src/style.css`. Use the palette tokens in your CSS.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import '@octane-xplat/ui/theme/tokens.css'
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```css
|
|
54
|
+
.trip-card {
|
|
55
|
+
background-color: var(--color-surface);
|
|
56
|
+
color: var(--color-text);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Use `useColorScheme()` to follow the system theme. Apply the matching class to
|
|
61
|
+
the root so the token colors follow the theme; a user preference can override
|
|
62
|
+
this in the starter's `src/App.tsrx`.
|
|
32
63
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
64
|
+
```tsrx
|
|
65
|
+
import { View, Text, useColorScheme } from '@octane-xplat/ui'
|
|
66
|
+
|
|
67
|
+
export function ThemePreview() {
|
|
68
|
+
const scheme = useColorScheme()
|
|
69
|
+
return <View className={scheme === 'dark' ? 'dark' : 'light'}>
|
|
70
|
+
<Text>Ready for your next trip</Text>
|
|
71
|
+
</View>
|
|
72
|
+
}
|
|
73
|
+
```
|
|
36
74
|
|
|
37
75
|
## Fonts
|
|
38
76
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
77
|
+
System fonts are the default. Add a custom font when your app needs one.
|
|
78
|
+
|
|
79
|
+
`pnpm xplat fonts add <file>` registers a font everywhere: stages a `.ttf`
|
|
80
|
+
into `src/fonts` (iOS/Android pick it up from there; `.woff`/`.woff2` inputs
|
|
81
|
+
are converted), writes the web `@font-face` into `src/fonts.css`, and wires
|
|
82
|
+
`--font-sans` (or another token via `--token mono|none|<name>`) in
|
|
83
|
+
`style.css`. Fontsource packages work too —
|
|
84
|
+
`pnpm xplat fonts add @fontsource-variable/inter --install` imports the
|
|
85
|
+
package's own CSS on web and stages its converted files natively (upright
|
|
86
|
+
faces only — italic files are skipped). Variable
|
|
87
|
+
fonts carry their weight range — `font-weight` on `Text` selects the matching
|
|
88
|
+
instance. Family names differ per target; the command reads them from the
|
|
89
|
+
file itself. See the styling guide at
|
|
42
90
|
https://octane-xplat.goddardai.org/styling for the per-target table.
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
pnpm xplat fonts add ./Inter.ttf
|
|
94
|
+
pnpm xplat fonts add @fontsource-variable/inter --install
|
|
95
|
+
```
|
package/template/AGENTS.md
CHANGED
package/template/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "octane-xplat-app",
|
|
3
3
|
"private": true,
|
|
4
4
|
"type": "module",
|
|
5
|
-
"main": "src/
|
|
5
|
+
"main": "src/main.ts",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"xplat": "xplat",
|
|
8
8
|
"dev": "vite",
|
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@nativescript-community/gesturehandler": "2.0.45",
|
|
20
|
-
"@nativescript-community/octane": "0.2.
|
|
20
|
+
"@nativescript-community/octane": "0.2.4",
|
|
21
21
|
"@nativescript-community/ui-drawer": "0.1.32",
|
|
22
22
|
"@nativescript/core": "9.1.2",
|
|
23
|
-
"@octane-xplat/effects": "^0.
|
|
24
|
-
"@octane-xplat/
|
|
23
|
+
"@octane-xplat/effects": "^0.10.0",
|
|
24
|
+
"@octane-xplat/platform": "^0.10.0",
|
|
25
|
+
"@octane-xplat/ui": "^0.10.0",
|
|
25
26
|
"@valor/nativescript-websockets": "2.0.3",
|
|
26
27
|
"octane": "0.6.3"
|
|
27
28
|
},
|
|
@@ -30,14 +31,15 @@
|
|
|
30
31
|
"@nativescript/android": "9.1.1",
|
|
31
32
|
"@nativescript/ios": "9.1.0",
|
|
32
33
|
"@nativescript/types": "9.0.0",
|
|
33
|
-
"@nativescript/vite": "8.0.
|
|
34
|
-
"@octane-xplat/cli": "^0.
|
|
35
|
-
"@octane-xplat/lint": "^0.
|
|
34
|
+
"@nativescript/vite": "8.0.17",
|
|
35
|
+
"@octane-xplat/cli": "^0.10.0",
|
|
36
|
+
"@octane-xplat/lint": "^0.10.0",
|
|
36
37
|
"@octanejs/vite-plugin": "0.1.61",
|
|
37
|
-
"@tsrx/typescript-plugin": "0.4.
|
|
38
|
+
"@tsrx/typescript-plugin": "0.4.11",
|
|
38
39
|
"nativescript": "9.1.1",
|
|
39
40
|
"oxlint": "^1.74.0",
|
|
40
41
|
"typescript": "5.9.3",
|
|
41
42
|
"vite": "8.3.0"
|
|
42
|
-
}
|
|
43
|
+
},
|
|
44
|
+
"packageManager": "pnpm@11.24.0"
|
|
43
45
|
}
|
|
@@ -14,14 +14,25 @@ allowBuilds:
|
|
|
14
14
|
'@parcel/watcher': true
|
|
15
15
|
nativescript: true
|
|
16
16
|
'@nativescript/core': false
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
|
|
17
|
+
# The patch set covers optional leaf deps (tiptap, linkifyjs, …) the starter
|
|
18
|
+
# doesn't install — tolerate entries that apply to nothing.
|
|
19
|
+
allowUnusedPatches: true
|
|
20
|
+
# Framework patches are supplied by the @octane-xplat/patches config dependency and
|
|
21
|
+
# applied via pnpm patchedDependencies. Managed upstream by @octane-xplat/cli (`xplat
|
|
22
|
+
# patches apply` refreshes, `xplat patches check` verifies); do not edit by hand.
|
|
20
23
|
patchedDependencies:
|
|
21
24
|
# Published octane 0.6.3 lacks live signal reads under universal renderers. Adds signal
|
|
22
25
|
# ownership, read tracking, and local signal hooks; JSX prop lowering and __methodDep
|
|
23
|
-
# already ship upstream.
|
|
24
|
-
|
|
26
|
+
# already ship upstream. Routes uncaught universal event-handler errors to onUncaughtError
|
|
27
|
+
# when configured. Pins instance signal/query declarations to their declaring owner so
|
|
28
|
+
# child reads and event handlers share one request. Makes universal useImperativeHandle
|
|
29
|
+
# honor optional refs, ref replacement, nested ref arrays, and callback cleanup. Also
|
|
30
|
+
# allows async and generator helpers that are not components in universal compiler
|
|
31
|
+
# modules, while preserving errors when those functions are used as components
|
|
32
|
+
# (octanejs/octane#1469). Adds renderer-owned Children.toArray/map for transparent
|
|
33
|
+
# deferred JSX groups, plan ranges/slots and arrays, preserving keyed wrapper identity
|
|
34
|
+
# while leaving scoped owners intact.
|
|
35
|
+
octane@0.6.3: node_modules/.pnpm-config/@octane-xplat/patches/patches/octane@0.6.3.patch
|
|
25
36
|
# FlexboxLayout getChildMeasureSpec subtracts the child's own padding where AOSP subtracts
|
|
26
37
|
# parent padding + child margins — a column-stretched row re-measurement clamps padded
|
|
27
38
|
# children (37→17 dip, squished controls). Adds squircle (continuous) corner clipping for
|
|
@@ -35,45 +46,67 @@ patchedDependencies:
|
|
|
35
46
|
# frames whose ancestors present them (Frame.topmost stops returning hidden preloaded tab
|
|
36
47
|
# frames). Also maps CSS font-weight to the OpenType wght axis for custom Android fonts on
|
|
37
48
|
# API 26+, preserves explicit variation settings, and falls back to the prior file load
|
|
38
|
-
# when the axis is unsupported.
|
|
39
|
-
|
|
49
|
+
# when the axis is unsupported. Carries NativeScript PR #11481: preserves percentage
|
|
50
|
+
# translate values through parsing and resolves each axis against the view's own
|
|
51
|
+
# dimensions, including native views and animations.
|
|
52
|
+
"@nativescript/core@9.1.2": node_modules/.pnpm-config/@octane-xplat/patches/patches/@nativescript__core@9.1.2.patch
|
|
53
|
+
# @nativescript/types@9.0.0 omits ambient declarations for the native URL and
|
|
54
|
+
# URLSearchParams globals, so projects without DOM libraries cannot typecheck valid native
|
|
55
|
+
# URL code. Adds runtime-aligned declarations that merge with DOM declarations when both
|
|
56
|
+
# libraries are present.
|
|
57
|
+
"@nativescript/types@9.0.0": node_modules/.pnpm-config/@octane-xplat/patches/patches/@nativescript__types@9.0.0.patch
|
|
40
58
|
# @nativescript/vite serializes bundled CSS and dev app.css through reworkcss `css`@3.0.0,
|
|
41
59
|
# which mis-parses @layer into garbage selectors — rules die before reaching
|
|
42
60
|
# _populateRules. Adds atlayer() covering block and statement forms. Applies to a
|
|
43
61
|
# transitive dep — no app declares it directly.
|
|
44
|
-
css@3.0.0: patches/css@3.0.0.patch
|
|
45
|
-
# Dev-server
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
|
|
62
|
+
css@3.0.0: node_modules/.pnpm-config/@octane-xplat/patches/patches/css@3.0.0.patch
|
|
63
|
+
# Dev-server fixes still missing after @nativescript/vite 8.0.17 added percent decoding
|
|
64
|
+
# for path-style /ns/m and Vue /ns/sfc requests (NativeScript#11483): collect re-export
|
|
65
|
+
# specifiers in the .vite/deps rewrite, route /@fs paths outside both roots through /ns/m
|
|
66
|
+
# (linked checkouts bypass the device transform upstream), and probe the non-active
|
|
67
|
+
# platform + `native` suffix tags in module candidates. The deps-bundle esbuild passes
|
|
68
|
+
# ignore vite resolve.alias, so a dep importing bare `octane` bundles the DOM runtime
|
|
69
|
+
# beside the universal one (hooks crash on boot, octane-xplat#3) — an onResolve plugin
|
|
70
|
+
# redirects `octane` → `octane/universal/native`. tsconfig-paths and the generated
|
|
71
|
+
# build-time checker moduleSuffixes also need the `.mobile` tier for iOS/Android/visionOS
|
|
72
|
+
# so `.mobile` leaves resolve under mapped imports and `ns build`. Served `/node_modules/`
|
|
73
|
+
# tails now also scan pnpm's `.pnpm` store and `link:`/`file:`/`portal:` dep roots — a
|
|
74
|
+
# linked package's transitive deps (e.g. @iconify/utils under @octane-xplat/icons) resolve
|
|
75
|
+
# nowhere else and 404 the dev session.
|
|
76
|
+
"@nativescript/vite@8.0.17": node_modules/.pnpm-config/@octane-xplat/patches/patches/@nativescript__vite@8.0.17.patch
|
|
56
77
|
# Driver setProp skips `undefined` writes — NativeScript native setters coerce it (e.g.
|
|
57
78
|
# editable → ios.userInteractionEnabled = NO), leaving dead UI that still has its JS
|
|
58
|
-
# listeners.
|
|
59
|
-
|
|
79
|
+
# listeners. Aligns intrinsic ref types with Octane callback cleanup and nested arrays
|
|
80
|
+
# with optional entries. Advertises the implemented visibility capability so committed
|
|
81
|
+
# suspense bodies can be retained while pending.
|
|
82
|
+
"@nativescript-community/octane@0.2.4": node_modules/.pnpm-config/@octane-xplat/patches/patches/@nativescript-community__octane@0.2.4.patch
|
|
60
83
|
# octaneServerStrategy's SCRIPT_FILE_RE only covers [jt]sx? — .tsrx edits never emit the
|
|
61
84
|
# deferred ns:hmr-delta broadcast, so component HMR silently never reaches the device.
|
|
62
85
|
# Also counts open /ns-hmr sockets so the update summary stops reporting recipients=0 for
|
|
63
86
|
# delivered updates.
|
|
64
|
-
"@nativescript-community/vite-octane@0.2.1": patches/@nativescript-community__vite-octane@0.2.1.patch
|
|
65
|
-
# Same dev-server fixes as the 8.0.11 patch, ported to the @11468 pkg.pr.new preview the
|
|
66
|
-
# windows target uses (apps/windows): /ns/m re-export records, vendor-manifest gating for
|
|
67
|
-
# plugin-patterned packages, percent-decoded specifiers, and the .mobile-aware
|
|
68
|
-
# tsconfig-paths probing.
|
|
69
|
-
"@nativescript/vite@8.0.13": patches/@nativescript__vite@8.0.13.patch
|
|
70
|
-
# Windows spike: the shared-file subset of the 9.1.2 patch — @layer cascade machinery
|
|
71
|
-
# (css-tree parser, css-selector, style-scope), the #11446 frame/tab-view common fixes,
|
|
72
|
-
# and the flexbox common measure-spec — applied to the @11468 preview. iOS/Android
|
|
73
|
-
# impl-file hunks are dead code on windows and were dropped.
|
|
74
|
-
"@nativescript/core@9.1.3-next.2": patches/@nativescript__core@9.1.3-next.2.patch
|
|
87
|
+
"@nativescript-community/vite-octane@0.2.1": node_modules/.pnpm-config/@octane-xplat/patches/patches/@nativescript-community__vite-octane@0.2.1.patch
|
|
75
88
|
# Enables `resolveHiddenExtensions` on the language plugin's typescript facet so
|
|
76
89
|
# extensionless specifiers (e.g. './Text') probe `.tsrx` after moduleSuffixes — required
|
|
77
90
|
# for a single extensionless shared barrel to resolve per-platform leaves under tsrx-tsc
|
|
78
91
|
# and the IDE plugin.
|
|
79
|
-
"@tsrx/typescript-plugin@0.4.11": patches/@tsrx__typescript-plugin@0.4.11.patch
|
|
92
|
+
"@tsrx/typescript-plugin@0.4.11": node_modules/.pnpm-config/@octane-xplat/patches/patches/@tsrx__typescript-plugin@0.4.11.patch
|
|
93
|
+
# linkifyjs declares /\p{L}/u and /\p{Emoji}/u as regex literals at module scope;
|
|
94
|
+
# NativeScript's embedded V8 builds without ICU, so the literals throw SyntaxError at
|
|
95
|
+
# parse time and poison the whole bundle (any bundled app importing @tiptap/extension-link
|
|
96
|
+
# dies on boot). Rewrites them as try/catch new RegExp builds with ASCII-range fallbacks —
|
|
97
|
+
# same behavior where ICU exists, graceful degradation where it doesn't.
|
|
98
|
+
linkifyjs@4.3.3: node_modules/.pnpm-config/@octane-xplat/patches/patches/linkifyjs@4.3.3.patch
|
|
99
|
+
# Two bundler-visible issues: useEditor.ts reads bare process.env.NODE_ENV (no node global
|
|
100
|
+
# in the harness typecheck program) and './Context' resolves to Context.tsrx — a
|
|
101
|
+
# self-import — under suffix-first resolution, so EditorContext/useCurrentEditor were
|
|
102
|
+
# unreachable. Adds a module-local process declaration for typecheck and merges the
|
|
103
|
+
# Context.ts definitions into Context.tsrx.
|
|
104
|
+
"@octanejs/tiptap@0.0.51": node_modules/.pnpm-config/@octane-xplat/patches/patches/@octanejs__tiptap@0.0.51.patch
|
|
105
|
+
# @lexical/link declares a /\p{L}\p{N}/u URL matcher as a regex literal at module scope;
|
|
106
|
+
# NativeScript's embedded V8 builds without ICU, so the literal throws SyntaxError at
|
|
107
|
+
# parse time and poisons the whole bundle (any bundled app importing @lexical/link dies on
|
|
108
|
+
# boot). Same fix as linkifyjs: try/catch new RegExp with an ASCII-range fallback — the
|
|
109
|
+
# matcher only feeds autolink, which native doesn't use.
|
|
110
|
+
"@lexical/link@0.51.0": node_modules/.pnpm-config/@octane-xplat/patches/patches/@lexical__link@0.51.0.patch
|
|
111
|
+
configDependencies:
|
|
112
|
+
"@octane-xplat/patches": 0.10.0
|
package/template/src/App.tsrx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useState } from 'octane';
|
|
2
|
-
import { View,
|
|
2
|
+
import { View, HStack, Text, Pressable, ScrollableArea, useColorScheme } from '@octane-xplat/ui';
|
|
3
|
+
import { storage } from '@octane-xplat/platform';
|
|
3
4
|
|
|
4
5
|
const FEATURES = [
|
|
5
6
|
'shared components',
|
|
@@ -13,8 +14,12 @@ const FEATURES = [
|
|
|
13
14
|
* (.web.tsrx / .mobile.tsrx), never inside a component. */
|
|
14
15
|
export function App() @{
|
|
15
16
|
const [count, setCount] = useState(0);
|
|
16
|
-
// null = follow the system
|
|
17
|
-
const [override, setOverride] = useState<boolean | null>(
|
|
17
|
+
// null = follow the system until the user chooses a mode.
|
|
18
|
+
const [override, setOverride] = useState<boolean | null>(() => {
|
|
19
|
+
const saved = storage.getString('theme-preference');
|
|
20
|
+
return saved === 'light' ? false : saved === 'dark' ? true : null;
|
|
21
|
+
});
|
|
22
|
+
|
|
18
23
|
const scheme = useColorScheme();
|
|
19
24
|
const dark = override ?? scheme === 'dark';
|
|
20
25
|
|
|
@@ -22,17 +27,21 @@ export function App() @{
|
|
|
22
27
|
<Text className="title">octane-xplat</Text>
|
|
23
28
|
<Text className="muted">one codebase — web · iOS · android</Text>
|
|
24
29
|
|
|
25
|
-
<
|
|
30
|
+
<HStack className="counter">
|
|
26
31
|
<Pressable className="btn" onPress={() => setCount(count - 1)}><Text>−</Text></Pressable>
|
|
27
32
|
<Text className="count">{count}</Text>
|
|
28
33
|
<Pressable className="btn" onPress={() => setCount(count + 1)}><Text>+</Text></Pressable>
|
|
29
|
-
</
|
|
34
|
+
</HStack>
|
|
30
35
|
|
|
31
|
-
<
|
|
36
|
+
<ScrollableArea>
|
|
32
37
|
{FEATURES.map((f) => <Text className="chip">{f}</Text>)}
|
|
33
|
-
</
|
|
38
|
+
</ScrollableArea>
|
|
34
39
|
|
|
35
|
-
<Pressable className="link" onPress={() =>
|
|
40
|
+
<Pressable className="link" onPress={() => {
|
|
41
|
+
const next = !dark;
|
|
42
|
+
storage.setString('theme-preference', next ? 'dark' : 'light');
|
|
43
|
+
setOverride(next);
|
|
44
|
+
}}>
|
|
36
45
|
<Text>{dark ? 'light' : 'dark'} mode (system: {scheme})</Text>
|
|
37
46
|
</Pressable>
|
|
38
47
|
</View>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// npm deps (upstream octane packages included) read `process.env.NODE_ENV`
|
|
2
|
+
// bare — the npm convention where the consumer bundler statically replaces
|
|
3
|
+
// the member expression (vite `define`; see xplatNodeEnvDefine). tsc still
|
|
4
|
+
// needs the name declared in a program with no Node types. Kept narrow on
|
|
5
|
+
// purpose: `process.env.FOO` reads stay type errors because the bundler
|
|
6
|
+
// define cannot rewrite them either.
|
|
7
|
+
declare const process: { env: { NODE_ENV?: string } }
|
package/template/src/style.css
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
|
-
/*
|
|
2
|
-
*
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/* This starter leaves the optional UI chrome stylesheet out. Define this
|
|
2
|
+
* app's palette here; the required tokens.css supplies layout structure. */
|
|
3
|
+
|
|
4
|
+
:root,
|
|
5
|
+
.ns-root {
|
|
6
|
+
--color-primary: #171717;
|
|
7
|
+
--color-onprimary: #fafafa;
|
|
8
|
+
--color-surface: #ffffff;
|
|
9
|
+
--color-text: #0a0a0a;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.dark,
|
|
13
|
+
.ns-dark {
|
|
14
|
+
--color-primary: #ededed;
|
|
15
|
+
--color-onprimary: #171717;
|
|
16
|
+
--color-surface: #0a0a0a;
|
|
17
|
+
--color-text: #ededed;
|
|
18
|
+
}
|
|
5
19
|
|
|
6
20
|
body {
|
|
7
21
|
margin: 0;
|
|
@@ -9,10 +23,12 @@ body {
|
|
|
9
23
|
background-color: var(--color-surface);
|
|
10
24
|
}
|
|
11
25
|
|
|
12
|
-
/* System-dark before JS mounts — no white flash.
|
|
13
|
-
*
|
|
26
|
+
/* System-dark before JS mounts — no white flash. .app.light below is the
|
|
27
|
+
* manual override back. */
|
|
14
28
|
@media (prefers-color-scheme: dark) {
|
|
15
29
|
:root {
|
|
30
|
+
--color-primary: #ededed;
|
|
31
|
+
--color-onprimary: #171717;
|
|
16
32
|
--color-surface: #0f172a;
|
|
17
33
|
--color-text: #f8fafc;
|
|
18
34
|
}
|
|
@@ -23,6 +39,8 @@ body {
|
|
|
23
39
|
|
|
24
40
|
/* Manual light override when the system is dark (JS adds .light). */
|
|
25
41
|
.app.light {
|
|
42
|
+
--color-primary: #171717;
|
|
43
|
+
--color-onprimary: #fafafa;
|
|
26
44
|
--color-surface: #ffffff;
|
|
27
45
|
--color-text: #111827;
|
|
28
46
|
}
|
package/template/tsconfig.json
CHANGED
|
@@ -3,6 +3,7 @@ import { xplatNative } from '@octane-xplat/cli/vite'
|
|
|
3
3
|
|
|
4
4
|
// The shared preset owns the renderer rules, octane→universal/native alias,
|
|
5
5
|
// suffix extension chain, deps-bundle plugin exclusions, the HMR watchdog,
|
|
6
|
-
//
|
|
7
|
-
// argument's `extra` (or
|
|
6
|
+
// the px→dip CSS rewrite, and fs.allow widening for link:/file: dep roots.
|
|
7
|
+
// App-specific additions go through the second argument's `extra` (or
|
|
8
|
+
// mergeConfig).
|
|
8
9
|
export default defineConfig(({ mode }) => xplatNative(mode))
|
package/template/vite.config.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { defineConfig } from 'vite'
|
|
2
2
|
import { octane } from '@octanejs/vite-plugin'
|
|
3
|
+
import { xplatBoundary, xplatNodeEnvDefine } from '@octane-xplat/cli/vite'
|
|
3
4
|
|
|
4
5
|
// The web build. For native (iOS/Android), the same source runs through
|
|
5
6
|
// @nativescript-community/vite-octane with `conditions: ['native']`, the
|
|
6
7
|
// .ios/.android/.mobile suffix chain, and the unsuffixed native default — see
|
|
7
8
|
// the octane-xplat repo's apps/mobile/vite.config.mts.
|
|
8
|
-
export default defineConfig({
|
|
9
|
-
plugins: [...octane()],
|
|
9
|
+
export default defineConfig(({ mode }) => ({
|
|
10
|
+
plugins: [...octane(), xplatBoundary('web')],
|
|
11
|
+
define: xplatNodeEnvDefine(mode),
|
|
10
12
|
server: { port: 5200 },
|
|
11
13
|
resolve: {
|
|
12
14
|
conditions: ['web'],
|
|
@@ -25,4 +27,4 @@ export default defineConfig({
|
|
|
25
27
|
'.json',
|
|
26
28
|
],
|
|
27
29
|
},
|
|
28
|
-
})
|
|
30
|
+
}))
|