Skip to content
Merged

Dev #239

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/release-ducpy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ jobs:
TAG=$(git describe --tags --abbrev=0 --match 'ducpy@*')
VERSION="${TAG#ducpy@}"
echo "Building Pyodide wheel for version ${VERSION}"
uv run python scripts/sync_schema.py
RUSTUP_TOOLCHAIN=nightly SETUPTOOLS_SCM_PRETEND_VERSION="${VERSION}" pyodide build --outdir dist

- name: Upload wheels to GitHub release
Expand Down
8 changes: 4 additions & 4 deletions packages/ducjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
"require": "./dist/index.js"
},
"./*": {
"types": ["./dist/*.d.ts", "./dist/*/index.d.ts"],
"import": ["./dist/*.js", "./dist/*/index.js"],
"require": ["./dist/*.js", "./dist/*/index.js"],
"types": ["./dist/*.d.ts", "./dist/*/index.d.ts"]
"require": ["./dist/*.js", "./dist/*/index.js"]
}
},
"scripts": {
Expand Down
8 changes: 4 additions & 4 deletions packages/ducjs/src/restore/restoreDataState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1147,18 +1147,18 @@ export const isValidImageStatusValue = (
export const isValidDucHead = (
value: DucHead | null | undefined,
blocks: RestoredDataState["blocks"],
elementScope: Scope,
currentScope: Scope
): DucHead | null => {
if (value === undefined || value === null) return null;
const type = isValidLineHeadValue(value.type);
// blockId can be null - only reject if type is invalid
if (type === null) return null;
const blockId = isValidBlockId(value.blockId, blocks);
const size = typeof value.size === "number" && Number.isFinite(value.size) && value.size > 0
? value.size
: 1;
return {
type,
blockId,
size: restorePrecisionValue(value.size, elementScope, currentScope),
size,
};
};

Expand Down
6 changes: 2 additions & 4 deletions packages/ducjs/src/restore/restoreElements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1415,9 +1415,7 @@ const repairBinding = (
),
head: isValidDucHead(
binding.head,
restoredBlocks,
elementScope,
currentScope
restoredBlocks
),
fixedPoint: element && isElbowArrow(element)
? normalizeFixedPoint(binding.fixedPoint ?? { x: 0.5, y: 0.5 })
Expand Down Expand Up @@ -1561,7 +1559,7 @@ const createHeadOnlyBinding = (
gap: getPrecisionValueFromRaw(0 as RawValue, currentScope, currentScope),
fixedPoint: null,
point: null,
head: isValidDucHead(head, restoredBlocks, currentScope, currentScope),
head: isValidDucHead(head, restoredBlocks),
};
};

Expand Down
4 changes: 2 additions & 2 deletions packages/ducjs/src/types/elements/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -760,8 +760,8 @@ export type DucPointBinding = {

export type DucHead = {
type: LineHead;
blockId: string | null; // If the head is a block, this is the id of the block
size: PrecisionValue;
blockId: string | null;
size: number;
}

export interface DucPointPosition {
Expand Down
42 changes: 37 additions & 5 deletions packages/ducjs/src/wasm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,40 @@ import init, {
let initialized = false;
let initPromise: Promise<void> | null = null;

const DEFAULT_WASM_URL = new URL("../dist/ducjs_wasm_bg.wasm", import.meta.url);

const isNodeRuntime = () =>
typeof process !== "undefined" && typeof process.versions?.node === "string";

type NodeFsPromisesModule = {
readFile(path: string | URL): Promise<Uint8Array>;
};

const loadNodeFsPromises = async (): Promise<NodeFsPromisesModule> => {
const dynamicImport = new Function("specifier", "return import(specifier)") as (
specifier: string,
) => Promise<NodeFsPromisesModule>;
return dynamicImport(["node", "fs/promises"].join(":"));
};

const resolveDefaultWasmInput = async (): Promise<URL | Uint8Array> => {
if (!isNodeRuntime()) {
return DEFAULT_WASM_URL;
}

const { readFile } = await loadNodeFsPromises();
const bytes = await readFile(DEFAULT_WASM_URL);
return new Uint8Array(bytes);
};

export async function ensureWasm(wasmUrl?: string | URL | BufferSource): Promise<void> {
if (initialized) return;
if (!initPromise) {
const arg = wasmUrl !== undefined ? { module_or_path: wasmUrl } : undefined;
initPromise = init(arg).then(() => {
initPromise = (async () => {
const moduleOrPath = wasmUrl ?? await resolveDefaultWasmInput();
await init({ module_or_path: moduleOrPath });
initialized = true;
});
})();
}
return initPromise;
}
Expand All @@ -35,8 +62,13 @@ export async function ensureWasm(wasmUrl?: string | URL | BufferSource): Promise
* without being able to resolve the file URL itself.
*/
export async function getWasmBinary(): Promise<ArrayBuffer> {
const url = new URL('../dist/ducjs_wasm_bg.wasm', import.meta.url);
const resp = await fetch(url);
if (isNodeRuntime()) {
const { readFile } = await loadNodeFsPromises();
const bytes = await readFile(DEFAULT_WASM_URL);
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as ArrayBuffer;
}

const resp = await fetch(DEFAULT_WASM_URL);
if (!resp.ok) {
throw new Error(`Failed to fetch WASM binary: ${resp.status} ${resp.statusText}`);
}
Expand Down
Loading
Loading