create-octane-xplat 0.1.0 → 0.3.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/package.json +1 -1
- package/template/.gitattributes +1 -0
- package/template/App_Resources/Android/app.gradle +25 -0
- package/template/App_Resources/Android/before-plugins.gradle +15 -0
- package/template/App_Resources/Android/src/main/AndroidManifest.xml +43 -0
- package/template/App_Resources/Android/src/main/res/drawable/ic_launcher_foreground.xml +15 -0
- package/template/App_Resources/Android/src/main/res/drawable-hdpi/background.png +0 -0
- package/template/App_Resources/Android/src/main/res/drawable-hdpi/logo.png +0 -0
- package/template/App_Resources/Android/src/main/res/drawable-ldpi/background.png +0 -0
- package/template/App_Resources/Android/src/main/res/drawable-ldpi/logo.png +0 -0
- package/template/App_Resources/Android/src/main/res/drawable-mdpi/background.png +0 -0
- package/template/App_Resources/Android/src/main/res/drawable-mdpi/logo.png +0 -0
- package/template/App_Resources/Android/src/main/res/drawable-nodpi/splash_screen.xml +8 -0
- package/template/App_Resources/Android/src/main/res/drawable-xhdpi/background.png +0 -0
- package/template/App_Resources/Android/src/main/res/drawable-xhdpi/logo.png +0 -0
- package/template/App_Resources/Android/src/main/res/drawable-xxhdpi/background.png +0 -0
- package/template/App_Resources/Android/src/main/res/drawable-xxhdpi/logo.png +0 -0
- package/template/App_Resources/Android/src/main/res/drawable-xxxhdpi/background.png +0 -0
- package/template/App_Resources/Android/src/main/res/drawable-xxxhdpi/logo.png +0 -0
- package/template/App_Resources/Android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/template/App_Resources/Android/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/template/App_Resources/Android/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/template/App_Resources/Android/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/template/App_Resources/Android/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/template/App_Resources/Android/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/template/App_Resources/Android/src/main/res/values/colors.xml +14 -0
- package/template/App_Resources/Android/src/main/res/values/ic_launcher_background.xml +4 -0
- package/template/App_Resources/Android/src/main/res/values/styles.xml +42 -0
- package/template/App_Resources/Android/src/main/res/values-v21/colors.xml +5 -0
- package/template/App_Resources/Android/src/main/res/values-v21/styles.xml +34 -0
- package/template/App_Resources/Android/src/main/res/values-v29/styles.xml +18 -0
- package/template/App_Resources/Android/src/main/res/xml/network_security_config.xml +14 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json +122 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-1024.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/Contents.json +6 -0
- package/template/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json +23 -0
- package/template/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@3x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json +23 -0
- package/template/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@3x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/octane.imageset/Contents.json +8 -0
- package/template/App_Resources/iOS/Assets.xcassets/octane.imageset/octane.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/octane.imageset/octane@2x.png +0 -0
- package/template/App_Resources/iOS/Assets.xcassets/octane.imageset/octane@3x.png +0 -0
- package/template/App_Resources/iOS/Info.plist +52 -0
- package/template/App_Resources/iOS/LaunchScreen.storyboard +53 -0
- package/template/App_Resources/iOS/build.xcconfig +7 -0
- package/template/App_Resources/iOS/src/OctaneShaders.metal +128 -0
- package/template/gitignore +2 -0
- package/template/index.html +1 -1
- package/template/nativescript.config.ts +13 -0
- package/template/package.json +19 -2
- package/template/patches/@nativescript-community__vite-octane@0.2.1.patch +41 -0
- package/template/patches/@nativescript__vite@8.0.11.patch +294 -0
- package/template/pnpm-workspace.yaml +25 -3
- package/template/references.d.ts +1 -0
- package/template/src/App.tsrx +5 -3
- package/template/src/native.ts +33 -0
- package/template/src/style.css +19 -0
- package/template/tsconfig.json +4 -2
- package/template/tsconfig.native.json +18 -0
- package/template/vite.config.native.mts +85 -0
- /package/template/src/{main.tsrx → main.web.tsrx} +0 -0
package/template/src/App.tsrx
CHANGED
|
@@ -13,10 +13,12 @@ const FEATURES = [
|
|
|
13
13
|
* (.web.tsrx / .native.tsrx), never inside a component. */
|
|
14
14
|
export function App() @{
|
|
15
15
|
const [count, setCount] = useState(0);
|
|
16
|
-
|
|
16
|
+
// null = follow the system; the toggle overrides it for this session.
|
|
17
|
+
const [override, setOverride] = useState<boolean | null>(null);
|
|
17
18
|
const scheme = useColorScheme();
|
|
19
|
+
const dark = override ?? scheme === 'dark';
|
|
18
20
|
|
|
19
|
-
<View className={['app', dark ? 'dark' : '']}>
|
|
21
|
+
<View className={['app', dark ? 'dark' : 'light']}>
|
|
20
22
|
<Text className="title">octane-xplat</Text>
|
|
21
23
|
<Text className="muted">one codebase — web · iOS · android</Text>
|
|
22
24
|
|
|
@@ -28,7 +30,7 @@ export function App() @{
|
|
|
28
30
|
|
|
29
31
|
<List items={FEATURES} renderItem={(f) => <Text className="chip">{f}</Text>} />
|
|
30
32
|
|
|
31
|
-
<Pressable className="link" onPress={() =>
|
|
33
|
+
<Pressable className="link" onPress={() => setOverride(!dark)}>
|
|
32
34
|
<Text>{dark ? 'light' : 'dark'} mode (system: {scheme})</Text>
|
|
33
35
|
</Pressable>
|
|
34
36
|
</View>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Native entry — the iOS/Android twin of main.web.tsrx. Same App.tsrx,
|
|
2
|
+
// different shell: a Frame hosting a Page that renders the universal root.
|
|
3
|
+
import { Application, Frame, Page } from '@nativescript/core';
|
|
4
|
+
import { renderNativeScriptApp } from '@nativescript-community/octane';
|
|
5
|
+
import { App } from './App.tsrx';
|
|
6
|
+
import '@octane-xplat/ui/theme/tokens.css';
|
|
7
|
+
import './style.css';
|
|
8
|
+
|
|
9
|
+
const entry = {
|
|
10
|
+
create: () => {
|
|
11
|
+
// Root is a Frame so pushRoute() can push Pages later — a Frame
|
|
12
|
+
// window root doubles as the 'root' stack with no registration;
|
|
13
|
+
// named stacks come from TabSpec.stack or registerStack. Route
|
|
14
|
+
// pushes also need registerScreens({name: Component}) at boot.
|
|
15
|
+
const frame = new Frame();
|
|
16
|
+
const page = new Page();
|
|
17
|
+
page.actionBarHidden = true;
|
|
18
|
+
renderNativeScriptApp(page, App);
|
|
19
|
+
frame.navigate({ create: () => page });
|
|
20
|
+
return frame;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Under the vite dev session the placeholder bootstrap has already run
|
|
25
|
+
// Application.run(), and a module-graph reload re-evaluates this entry.
|
|
26
|
+
// Android's run() throws "Application is already started" on re-entry
|
|
27
|
+
// (iOS core handles the placeholder handoff internally); resetRootView is
|
|
28
|
+
// the documented way to swap the root of a running app.
|
|
29
|
+
if (Application.started) {
|
|
30
|
+
Application.resetRootView(entry);
|
|
31
|
+
} else {
|
|
32
|
+
Application.run(entry);
|
|
33
|
+
}
|
package/template/src/style.css
CHANGED
|
@@ -6,6 +6,25 @@
|
|
|
6
6
|
body {
|
|
7
7
|
margin: 0;
|
|
8
8
|
font-family: system-ui, sans-serif;
|
|
9
|
+
background-color: var(--color-surface);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/* System-dark before JS mounts — no white flash. Same values tokens.css
|
|
13
|
+
* sets under .dark; .app.light below is the manual override back. */
|
|
14
|
+
@media (prefers-color-scheme: dark) {
|
|
15
|
+
:root {
|
|
16
|
+
--color-surface: #0f172a;
|
|
17
|
+
--color-text: #f8fafc;
|
|
18
|
+
}
|
|
19
|
+
body {
|
|
20
|
+
background-color: var(--color-surface);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* Manual light override when the system is dark (JS adds .light). */
|
|
25
|
+
.app.light {
|
|
26
|
+
--color-surface: #ffffff;
|
|
27
|
+
--color-text: #111827;
|
|
9
28
|
}
|
|
10
29
|
|
|
11
30
|
.app {
|
package/template/tsconfig.json
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
"customConditions": ["web"],
|
|
11
11
|
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
12
12
|
"types": ["vite/client"],
|
|
13
|
-
"noEmit": true
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"skipLibCheck": true
|
|
14
15
|
},
|
|
15
|
-
"include": ["src/**/*"]
|
|
16
|
+
"include": ["src/**/*"],
|
|
17
|
+
"exclude": ["node_modules", "src/native.ts"]
|
|
16
18
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"strict": true,
|
|
4
|
+
"target": "ESNext",
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"jsx": "preserve",
|
|
8
|
+
"jsxImportSource": "@nativescript-community/octane",
|
|
9
|
+
"moduleSuffixes": [".ios", ".android", ".native", ""],
|
|
10
|
+
"customConditions": ["native"],
|
|
11
|
+
"lib": ["ESNext"],
|
|
12
|
+
"types": ["@nativescript/types"],
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"skipLibCheck": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*", "references.d.ts"],
|
|
17
|
+
"exclude": ["node_modules", "platforms", "**/*.web.*"]
|
|
18
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { defineConfig, mergeConfig, type Plugin } from 'vite';
|
|
2
|
+
import { octaneConfig } from '@nativescript-community/vite-octane';
|
|
3
|
+
import { nativeScriptRenderer } from '@nativescript-community/octane/config';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* On-device HMR needs the app's websocket client to attach to /ns-hmr after
|
|
7
|
+
* the HTTP boot. When it never does — the @valor/nativescript-websockets
|
|
8
|
+
* polyfill missing from the bundle, `adb reverse` not covering the vite port,
|
|
9
|
+
* or a boot error before the client import — every save logs `recipients=0`
|
|
10
|
+
* and the device silently stays stale. Warn once when a dev session was
|
|
11
|
+
* fetched but no client ever attached.
|
|
12
|
+
*/
|
|
13
|
+
function nsHmrClientWatchdog(): Plugin {
|
|
14
|
+
return {
|
|
15
|
+
name: 'ns-hmr-client-watchdog',
|
|
16
|
+
configureServer(server) {
|
|
17
|
+
let everConnected = false;
|
|
18
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
19
|
+
// Hook the raw 'request' event — middlewares.use() appends after the
|
|
20
|
+
// ns plugin's session handler, which ends the response without next(),
|
|
21
|
+
// so a connect middleware never observes /__ns_dev__/session at all.
|
|
22
|
+
server.httpServer?.on('request', (req) => {
|
|
23
|
+
if (!everConnected && req.url?.startsWith('/__ns_dev__/session')) {
|
|
24
|
+
clearTimeout(timer);
|
|
25
|
+
timer = setTimeout(() => {
|
|
26
|
+
if (!everConnected) {
|
|
27
|
+
console.warn(
|
|
28
|
+
'[ns-hmr-client-watchdog] the app fetched its dev session ' +
|
|
29
|
+
'but no /ns-hmr websocket client connected — edits will not ' +
|
|
30
|
+
'reach the device. Check that @valor/nativescript-websockets ' +
|
|
31
|
+
'is installed, `adb reverse tcp:<port>` covers this vite port ' +
|
|
32
|
+
'(physical Android), and the device log for hmr-client errors.',
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
}, 15_000);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
server.httpServer?.on('upgrade', (req) => {
|
|
39
|
+
if (req.url?.startsWith('/ns-hmr')) {
|
|
40
|
+
everConnected = true;
|
|
41
|
+
clearTimeout(timer);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// The native build (iOS/Android). @octane-xplat/ui resolves through the
|
|
49
|
+
// package's `native` export condition → compiled dist/native — no .tsrx
|
|
50
|
+
// leaves needed from node_modules, so the renderer rule covers src/ only.
|
|
51
|
+
export default defineConfig(({ mode }) =>
|
|
52
|
+
mergeConfig(
|
|
53
|
+
octaneConfig(
|
|
54
|
+
{ mode },
|
|
55
|
+
{
|
|
56
|
+
octane: {
|
|
57
|
+
renderers: {
|
|
58
|
+
registry: { nativescript: nativeScriptRenderer },
|
|
59
|
+
rules: [
|
|
60
|
+
{ include: 'src/**/*.{ts,tsx,tsrx}', renderer: 'nativescript' },
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
),
|
|
66
|
+
{
|
|
67
|
+
plugins: [nsHmrClientWatchdog()],
|
|
68
|
+
resolve: {
|
|
69
|
+
conditions: ['native'],
|
|
70
|
+
// The deps-bundle scanner sees source-level 'octane' imports
|
|
71
|
+
// before the compiler retargets hooks — without this it vendors
|
|
72
|
+
// the DOM runtime. Exact match only.
|
|
73
|
+
alias: [{ find: /^octane$/, replacement: 'octane/universal/native' }],
|
|
74
|
+
preserveSymlinks: false,
|
|
75
|
+
// Suffix chain (first match wins): .ios/.android → .native → shared.
|
|
76
|
+
extensions: [
|
|
77
|
+
'.ios.tsrx', '.android.tsrx', '.native.tsrx', '.tsrx',
|
|
78
|
+
'.ios.tsx', '.android.tsx', '.native.tsx', '.tsx',
|
|
79
|
+
'.ios.ts', '.android.ts', '.native.ts', '.mjs', '.mts', '.ts',
|
|
80
|
+
'.jsx', '.js', '.json',
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
),
|
|
85
|
+
);
|
|
File without changes
|