@octane-xplat/canvas 0.0.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Alec Larson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,35 @@
1
+ import { defineUniversalComponent, registerElement, universalPlan, universalValue } from "@nativescript-community/octane";
2
+ import { Canvas } from "@nativescript/canvas";
3
+ //#region src/Canvas.tsrx
4
+ var __octaneUniversalPlan0 = universalPlan("nativescript", {
5
+ "kind": "host",
6
+ "type": "nscanvas",
7
+ "bindings": [
8
+ ["id", 0],
9
+ ["className", 1],
10
+ ["style", 2],
11
+ ["width", 3],
12
+ ["height", 4],
13
+ ["onReady", 5]
14
+ ]
15
+ });
16
+ registerElement("nscanvas", Canvas);
17
+ var Canvas$1 = defineUniversalComponent("nativescript", function Canvas(props) {
18
+ const ready = (event) => {
19
+ const canvas = event.object;
20
+ props.onReady?.({
21
+ canvas,
22
+ context: props.context ? canvas.getContext(props.context) : null
23
+ });
24
+ };
25
+ return universalValue(__octaneUniversalPlan0, [
26
+ props.id,
27
+ props.className,
28
+ props.style,
29
+ props.width,
30
+ props.height,
31
+ ready
32
+ ]);
33
+ }, { "module": "@nativescript-community/octane" });
34
+ //#endregion
35
+ export { Canvas$1 as Canvas };
@@ -0,0 +1,10 @@
1
+ import { GPU } from "@nativescript/canvas";
2
+ //#region src/gpu.ts
3
+ /** getGPU — returns the plugin's GPU shim (wgpu over Metal/Vulkan). Same
4
+ * spec-shaped surface as web's `navigator.gpu`: `requestAdapter()` +
5
+ * `getPreferredCanvasFormat()`. */
6
+ function getGPU() {
7
+ return new GPU();
8
+ }
9
+ //#endregion
10
+ export { getGPU };
@@ -0,0 +1,3 @@
1
+ import { Canvas } from "./Canvas.tsrx.js";
2
+ import { getGPU } from "./gpu.js";
3
+ export { Canvas, getGPU };
@@ -0,0 +1,8 @@
1
+ {
2
+ "version": 1,
3
+ "buildId": "53e9debf-4f85-43bc-9b14-599d14aeeaef",
4
+ "mode": "production",
5
+ "capabilities": {
6
+ "independentHydration": false
7
+ }
8
+ }
@@ -0,0 +1,50 @@
1
+ import { __s, bag7, clone, queueRefAttach, queueRefDetach, setStyle, template } from "octane";
2
+ import { bindSignalAttribute, enableSignalBindings, replaceRef, setPlainAttribute } from "octane/internal/client";
3
+ //#region src/Canvas.web.tsrx
4
+ enableSignalBindings(1, true);
5
+ var _t$0 = /* @__PURE__ */ template("<canvas></canvas>");
6
+ var _rm$0 = [
7
+ "r",
8
+ "g",
9
+ "b"
10
+ ];
11
+ var Canvas = /* @__PURE__ */ __s(function Canvas(props, __s, __extra) {
12
+ let _b = __s.slots[0];
13
+ if (_b === void 0) {
14
+ let _m1, _m6;
15
+ const _root = clone(_t$0);
16
+ _m1 = _root;
17
+ queueRefAttach(__s, _m6 = (el) => {
18
+ if (!el) return;
19
+ props.onReady?.({
20
+ canvas: el,
21
+ context: props.context ? el.getContext(props.context) : null
22
+ });
23
+ }, _m1);
24
+ (__s.cleanups ??= []).push(() => _b && queueRefDetach(_b.g, _b.b));
25
+ _b = bag7(__s, _root, void 0, _m1, void 0, void 0, void 0, void 0, _m6);
26
+ __s.refFields = _rm$0;
27
+ } else {
28
+ const _r = (el) => {
29
+ if (!el) return;
30
+ props.onReady?.({
31
+ canvas: el,
32
+ context: props.context ? el.getContext(props.context) : null
33
+ });
34
+ };
35
+ if (_r !== _b.g) _b.g = replaceRef(__s, _b.g, _r, _b.b);
36
+ }
37
+ _b.a = bindSignalAttribute(__s, _b.a, _b.b, "id", props.id, "b:f0c24829", setPlainAttribute);
38
+ _b.c = bindSignalAttribute(__s, _b.c, _b.b, "class", props.className, "b:ea9117bd", "class");
39
+ {
40
+ const _v = props.style;
41
+ if (_b.d !== _v) {
42
+ setStyle(_b.b, _v, _b.d);
43
+ _b.d = _v;
44
+ }
45
+ }
46
+ _b.e = bindSignalAttribute(__s, _b.e, _b.b, "width", typeof props.width === "number" ? props.width : void 0, "b:b4becda6", setPlainAttribute);
47
+ _b.f = bindSignalAttribute(__s, _b.f, _b.b, "height", typeof props.height === "number" ? props.height : void 0, "b:7ec30b3a", setPlainAttribute);
48
+ });
49
+ //#endregion
50
+ export { Canvas };
@@ -0,0 +1,10 @@
1
+ //#region src/gpu.web.ts
2
+ /** getGPU — returns the WebGPU entry point (`navigator.gpu`) or null when
3
+ * WebGPU is unavailable (insecure context, unsupported browser). The
4
+ * returned object is spec-shaped: `requestAdapter()` +
5
+ * `getPreferredCanvasFormat()`. */
6
+ function getGPU() {
7
+ return globalThis.navigator?.gpu ?? null;
8
+ }
9
+ //#endregion
10
+ export { getGPU };
@@ -0,0 +1,3 @@
1
+ import { Canvas } from "./Canvas.web.tsrx.js";
2
+ import { getGPU } from "./gpu.web.js";
3
+ export { Canvas, getGPU };
@@ -0,0 +1,8 @@
1
+ {
2
+ "version": 1,
3
+ "buildId": "15151704-61a3-4d60-b8bb-51699b32231d",
4
+ "mode": "production",
5
+ "capabilities": {
6
+ "independentHydration": false
7
+ }
8
+ }
package/package.json CHANGED
@@ -1,6 +1,69 @@
1
1
  {
2
- "name": "@octane-xplat/canvas",
3
- "version": "0.0.0",
4
- "description": "Stub reserving the name; real releases publish from CI via trusted publishing.",
5
- "publishConfig": {"access": "public"}
6
- }
2
+ "name": "@octane-xplat/canvas",
3
+ "version": "0.7.1",
4
+ "description": "Canvas/GPU surface for Octane xplat — web <canvas> + @nativescript/canvas (2D, WebGL/WebGL2, WebGPU/WGSL)",
5
+ "keywords": [
6
+ "octane",
7
+ "xplat",
8
+ "cross-platform",
9
+ "canvas",
10
+ "webgl",
11
+ "webgl2",
12
+ "webgpu",
13
+ "wgsl",
14
+ "gpu",
15
+ "graphics",
16
+ "nativescript"
17
+ ],
18
+ "license": "MIT",
19
+ "homepage": "https://github.com/octane-xplat/octane-xplat/tree/main/packages/canvas",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/octane-xplat/octane-xplat.git",
23
+ "directory": "packages/canvas"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "types",
28
+ "src"
29
+ ],
30
+ "type": "module",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./types/index.d.ts",
34
+ "web": "./dist/web/index.js",
35
+ "native": "./dist/native/index.js",
36
+ "default": "./dist/native/index.js"
37
+ }
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "dependencies": {
43
+ "@nativescript/canvas": "3.0.0-alpha.15"
44
+ },
45
+ "devDependencies": {
46
+ "@nativescript-community/octane": "0.2.1",
47
+ "@nativescript/core": "9.1.2",
48
+ "@octanejs/vite-plugin": "0.1.61",
49
+ "octane": "0.6.3",
50
+ "typescript": "5.9.3",
51
+ "vite": "8.3.0"
52
+ },
53
+ "peerDependencies": {
54
+ "@nativescript-community/octane": ">=0.2.1 <1",
55
+ "@nativescript/core": ">=9.1.0 <10",
56
+ "octane": ">=0.6.3 <1"
57
+ },
58
+ "peerDependenciesMeta": {
59
+ "@nativescript-community/octane": {
60
+ "optional": true
61
+ },
62
+ "@nativescript/core": {
63
+ "optional": true
64
+ }
65
+ },
66
+ "scripts": {
67
+ "build": "vite build && vite build --mode native && tsc -p tsconfig.types.json && node ../../scripts/check-native-dist.mjs"
68
+ }
69
+ }
@@ -0,0 +1,39 @@
1
+ /** @jsxImportSource @nativescript-community/octane */
2
+ import { registerElement } from '@nativescript-community/octane';
3
+ import type { Attributes } from '@nativescript-community/octane/intrinsics';
4
+ import { Canvas as NSCanvas } from '@nativescript/canvas';
5
+ import type { CanvasProps } from './props';
6
+
7
+ declare module '@nativescript-community/octane/intrinsics' {
8
+ interface NativeScriptElements {
9
+ nscanvas: Attributes<typeof NSCanvas>;
10
+ }
11
+ }
12
+
13
+ // @nativescript/canvas — Skia + wgpu core exposing the DOM Canvas API
14
+ // (2d, webgl, webgl2, webgpu) on iOS + Android. Element name is `nscanvas`
15
+ // rather than `canvas` because `canvas` is DOM vocabulary in the
16
+ // element-vocabulary lint.
17
+ registerElement('nscanvas', NSCanvas);
18
+
19
+ /** Canvas — DOM Canvas API surface on native. `onReady` wraps the plugin's
20
+ * `ready` event: it fires once the GPU surface exists, which is the
21
+ * earliest `getContext` may be called. */
22
+ export function Canvas(props: CanvasProps) @{
23
+ const ready = (event: any) => {
24
+ const canvas = event.object;
25
+ props.onReady?.({
26
+ canvas,
27
+ context: props.context ? canvas.getContext(props.context) : null,
28
+ });
29
+ };
30
+
31
+ <nscanvas
32
+ id={props.id}
33
+ className={props.className}
34
+ style={props.style}
35
+ width={props.width as any}
36
+ height={props.height as any}
37
+ onReady={ready}
38
+ />;
39
+ }
@@ -0,0 +1,23 @@
1
+ import type { CanvasProps } from './props';
2
+
3
+ /** Canvas — a plain <canvas>. `onReady` fires at mount with the element
4
+ * and the resolved context. */
5
+ export function Canvas(props: CanvasProps) @{
6
+ <canvas
7
+ id={props.id}
8
+ className={props.className}
9
+ style={props.style}
10
+ width={typeof props.width === 'number' ? props.width : undefined}
11
+ height={typeof props.height === 'number' ? props.height : undefined}
12
+ ref={(el: HTMLCanvasElement | null) => {
13
+ if (!el) {
14
+ return;
15
+ }
16
+
17
+ props.onReady?.({
18
+ canvas: el,
19
+ context: props.context ? el.getContext(props.context) : null,
20
+ });
21
+ }}
22
+ />
23
+ }
package/src/gpu.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { GPU } from '@nativescript/canvas';
2
+
3
+ /** getGPU — returns the plugin's GPU shim (wgpu over Metal/Vulkan). Same
4
+ * spec-shaped surface as web's `navigator.gpu`: `requestAdapter()` +
5
+ * `getPreferredCanvasFormat()`. */
6
+ export function getGPU(): any {
7
+ return new GPU();
8
+ }
package/src/gpu.web.ts ADDED
@@ -0,0 +1,7 @@
1
+ /** getGPU — returns the WebGPU entry point (`navigator.gpu`) or null when
2
+ * WebGPU is unavailable (insecure context, unsupported browser). The
3
+ * returned object is spec-shaped: `requestAdapter()` +
4
+ * `getPreferredCanvasFormat()`. */
5
+ export function getGPU(): any {
6
+ return (globalThis.navigator as any)?.gpu ?? null;
7
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ // Platform barrels — explicit .tsrx leaf imports (moduleSuffixes don't
2
+ // reach .tsrx; same convention as @octane-xplat/ui index.*.ts).
3
+ export { Canvas } from './Canvas.tsrx';
4
+ export { getGPU } from './gpu';
5
+ export type { CanvasProps, CanvasContextKind, CanvasReady } from './props';
@@ -0,0 +1,5 @@
1
+ // Platform barrels — explicit .tsrx leaf imports (moduleSuffixes don't
2
+ // reach .tsrx; same convention as @octane-xplat/ui index.*.ts).
3
+ export { Canvas } from './Canvas.web.tsrx';
4
+ export { getGPU } from './gpu.web';
5
+ export type { CanvasProps, CanvasContextKind, CanvasReady } from './props';
package/src/props.ts ADDED
@@ -0,0 +1,33 @@
1
+ export type CanvasContextKind =
2
+ | '2d'
3
+ | 'webgl'
4
+ | 'webgl2'
5
+ | 'webgpu'
6
+ | 'bitmaprenderer';
7
+
8
+ export interface CanvasReady {
9
+ /** HTMLCanvasElement on web, the plugin's Canvas view on native —
10
+ * both expose `getContext()`. */
11
+ canvas: any;
12
+ /** The resolved context for the `context` prop, or null when that
13
+ * kind is unsupported/unavailable. WebGPU still needs a device —
14
+ * `getGPU()` normalizes adapter/device acquisition. */
15
+ context: any;
16
+ }
17
+
18
+ export interface CanvasProps {
19
+ className?: any;
20
+ style?: any;
21
+ id?: string;
22
+ /** Context kind resolved before `onReady` fires. Omit to defer
23
+ * `getContext` to user code (only one kind per canvas — call once). */
24
+ context?: CanvasContextKind;
25
+ /** Web: after mount. Native: the plugin's `ready` event (fires when the
26
+ * GPU surface exists — earlier `getContext` calls can return null). */
27
+ onReady?: (ready: CanvasReady) => void;
28
+ /** Numeric values map to the element's width/height — on web that is
29
+ * the canvas *drawing buffer* size (pair with style for display
30
+ * size), on native dip size. */
31
+ width?: string | number;
32
+ height?: string | number;
33
+ }
@@ -0,0 +1,13 @@
1
+ // Boundary types for @octane-xplat/canvas — the mechanical wrapper over
2
+ // props.ts (tsrx-tsc can't emit .tsrx declarations; see ui/types/index.d.ts
3
+ // for the same pattern).
4
+ import type { UniversalComponent } from 'octane/universal'
5
+ import type { CanvasProps } from './props'
6
+
7
+ export declare const Canvas: UniversalComponent<CanvasProps>
8
+
9
+ /** Returns the WebGPU entry point — `navigator.gpu` on web, the plugin's
10
+ * GPU shim on native — or null where WebGPU is unavailable. */
11
+ export declare function getGPU(): any
12
+
13
+ export type { CanvasProps, CanvasContextKind, CanvasReady } from './props'
@@ -0,0 +1,26 @@
1
+ export type CanvasContextKind = '2d' | 'webgl' | 'webgl2' | 'webgpu' | 'bitmaprenderer';
2
+ export interface CanvasReady {
3
+ /** HTMLCanvasElement on web, the plugin's Canvas view on native —
4
+ * both expose `getContext()`. */
5
+ canvas: any;
6
+ /** The resolved context for the `context` prop, or null when that
7
+ * kind is unsupported/unavailable. WebGPU still needs a device —
8
+ * `getGPU()` normalizes adapter/device acquisition. */
9
+ context: any;
10
+ }
11
+ export interface CanvasProps {
12
+ className?: any;
13
+ style?: any;
14
+ id?: string;
15
+ /** Context kind resolved before `onReady` fires. Omit to defer
16
+ * `getContext` to user code (only one kind per canvas — call once). */
17
+ context?: CanvasContextKind;
18
+ /** Web: after mount. Native: the plugin's `ready` event (fires when the
19
+ * GPU surface exists — earlier `getContext` calls can return null). */
20
+ onReady?: (ready: CanvasReady) => void;
21
+ /** Numeric values map to the element's width/height — on web that is
22
+ * the canvas *drawing buffer* size (pair with style for display
23
+ * size), on native dip size. */
24
+ width?: string | number;
25
+ height?: string | number;
26
+ }