lecodes-cli 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -854,7 +854,12 @@ var compileProject = async (opts) => {
854
854
  const files = {};
855
855
  for (const e of opts.entries) {
856
856
  if (e.type === "resource") {
857
- files[e.path] = `export default "${opts.publicUrl}${e.fileSrc ?? ""}"`;
857
+ if (opts.localAssets) {
858
+ const name = e.path.split(/[\\/]/).pop() ?? e.path;
859
+ files[e.path] = `export default ("id:" + _creatorUtils.fetchLocal(${JSON.stringify(name)}))`;
860
+ } else {
861
+ files[e.path] = `export default "${opts.publicUrl}${e.fileSrc ?? ""}"`;
862
+ }
858
863
  } else if (e.type === "shader") {
859
864
  const shaders = e.shaders ?? [];
860
865
  if (shaders.length > 2) {
@@ -905,7 +910,8 @@ var compileProject2 = (opts) => compileProject({
905
910
  publicUrl: opts.publicUrl,
906
911
  entryOverride: opts.entryOverride,
907
912
  header: opts.header,
908
- format: opts.format
913
+ format: opts.format,
914
+ localAssets: opts.localAssets
909
915
  });
910
916
 
911
917
  // src/compile/designCompile.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lecodes-cli",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Clone, edit and push LeCodes projects from your machine.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -21,17 +21,18 @@
21
21
  },
22
22
  "scripts": {
23
23
  "vendor-runtime": "bun scripts/vendor-runtime.ts",
24
+ "sync-peers": "bun scripts/sync-peer-versions.ts",
24
25
  "build": "bun scripts/vendor-runtime.ts && bun build src/index.ts --target=node --outfile dist/index.js --external @letary/chisel --external lecodes-renderer --external lecodes-design --banner=\"#!/usr/bin/env node\"",
25
26
  "typecheck": "tsc --noEmit",
26
27
  "dev": "bun run src/index.ts",
27
- "prepublishOnly": "bun run build"
28
+ "prepublishOnly": "bun run sync-peers && bun run build"
28
29
  },
29
30
  "dependencies": {
30
31
  "@letary/chisel": "^0.2.0"
31
32
  },
32
33
  "peerDependencies": {
33
34
  "lecodes-design": "^0.1.0",
34
- "lecodes-renderer": "^0.4.0"
35
+ "lecodes-renderer": "^0.4.1"
35
36
  },
36
37
  "peerDependenciesMeta": {
37
38
  "lecodes-design": {
@@ -43,7 +44,7 @@
43
44
  },
44
45
  "devDependencies": {
45
46
  "lecodes-design": "workspace:*",
46
- "lecodes-renderer": "workspace:*",
47
+ "lecodes-renderer": "^0.4.1",
47
48
  "sdk": "workspace:*"
48
49
  }
49
50
  }
@@ -21,7 +21,8 @@
21
21
  // new Sprite({ texture: c }) // Canvas is a valid texture source everywhere
22
22
 
23
23
  import { Texture2D } from "../g2/Texture2D"
24
- import { File } from "../runtime/fetch"
24
+ import { File, type FetchResponse } from "../runtime/fetch"
25
+ import type { SvgSourceValue } from "../runtime/misc"
25
26
 
26
27
  // Opcodes — MUST stay in sync with docs/canvas-contract.md.
27
28
  const OP = {
@@ -167,6 +168,24 @@ export class Canvas {
167
168
  return this
168
169
  }
169
170
 
171
+ /** Decode an image source into a standalone `Bitmap` you can blit with `drawImage()` — either an
172
+ * `SvgSource(...)` (rasterized) or a `FetchResponse` holding already-fetched image bytes (decoded).
173
+ * This is async because turning SVG markup / encoded bytes into pixels needs a decode step (on the
174
+ * web, `createImageBitmap` / an `<img>` load); `await` it ONCE, then `drawImage(bitmap, …)` is
175
+ * synchronous and the Bitmap is reusable. The returned Bitmap owns a native surface at the image's
176
+ * natural pixel size (`pixelRatio` 1) — `destroy()` it when done. Typical use:
177
+ * const logo = await canvas.loadImage(SvgSource(svg)) // or: await fetch(url) → the response
178
+ * canvas.drawImage(logo, 0, 0) // sync, blit as often as you like */
179
+ loadImage(source: SvgSourceValue | FetchResponse): Promise<Bitmap> {
180
+ // Discriminate without touching FetchResponse internals: only an SvgSource carries `.svg`.
181
+ const isSvg = typeof (source as SvgSourceValue).svg === "string"
182
+ const svg = isSvg ? (source as SvgSourceValue).svg : ""
183
+ const bufferId = isSvg ? -1 : (source as any)._id // <0 = the SVG path; else the host buffer id
184
+ return new Promise<Bitmap>((res, rej) => {
185
+ _creatorCanvas.loadImage(svg, bufferId, (surfaceId, w, h) => res(new Bitmap(surfaceId, w, h, 1)), rej)
186
+ })
187
+ }
188
+
170
189
  /** Measure `text` in the current font on THIS platform. The one synchronous round-trip. */
171
190
  measureText(text: string): CanvasTextMetrics {
172
191
  const o = _creatorCanvas.measureText(text, this._font)
@@ -31,6 +31,11 @@ export type CompileOptions = {
31
31
  icon?: string
32
32
  /** "esm" (default, shipped) or "iife" (self-running, for the local renderer). */
33
33
  format?: "esm" | "iife"
34
+ /** Resolve `asset()` resources to a LOCAL host asset at runtime instead of a `publicUrl` URL: each
35
+ * resource compiles to `"id:" + _creatorUtils.fetchLocal(<name>)` (the host reads the file by name
36
+ * and returns its systemId). For hosts with no asset server (the desktop native host), where a URL
37
+ * can't be fetched. Off by default — the shipped/web build keeps the URL form. */
38
+ localAssets?: boolean
34
39
  }
35
40
 
36
41
  /** The default entrypoint: the largest top-level .ts/.js file with no `export` (a script entry). */
@@ -55,7 +60,14 @@ export const compileProject = async (opts: CompileOptions): Promise<string> => {
55
60
  const files: Record<string, string> = {}
56
61
  for (const e of opts.entries) {
57
62
  if (e.type === "resource") {
58
- files[e.path] = `export default "${opts.publicUrl}${e.fileSrc ?? ""}"`
63
+ if (opts.localAssets) {
64
+ // The host resolves the asset by name at runtime (reads the local file → systemId); the
65
+ // "id:" prefix is the host's local-resource URL scheme (parsed by the UI + 2D texture paths).
66
+ const name = e.path.split(/[\\/]/).pop() ?? e.path
67
+ files[e.path] = `export default ("id:" + _creatorUtils.fetchLocal(${JSON.stringify(name)}))`
68
+ } else {
69
+ files[e.path] = `export default "${opts.publicUrl}${e.fileSrc ?? ""}"`
70
+ }
59
71
  } else if (e.type === "shader") {
60
72
  const shaders = e.shaders ?? []
61
73
  if (shaders.length > 2) {