From d1dd0274aa0a6e747918545bcf815c90ae08eda7 Mon Sep 17 00:00:00 2001 From: David Herman Date: Sun, 10 Dec 2023 13:52:57 -0800 Subject: [PATCH] new alternative APIs for `load`: - loader(): returns a thunk, which means users don't need to specify the exports but have to remember to lazily apply the thunk to guarantee laziness - proxy(): returns a proxy, which means users don't need to specify the exports and always get the correct lazy behavior no matter what right now hidden behind ugly `__UNSTABLE_foo` names --- pkgs/cargo-messages/lib/load.cjs | 11 +++++ pkgs/load/src/index.ts | 70 ++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/pkgs/cargo-messages/lib/load.cjs b/pkgs/cargo-messages/lib/load.cjs index ce04b3ec..073204f2 100644 --- a/pkgs/cargo-messages/lib/load.cjs +++ b/pkgs/cargo-messages/lib/load.cjs @@ -1,3 +1,14 @@ +// module.exports = require('@neon-rs/load').__UNSTABLE_proxy({ +// 'darwin-x64': () => require('@cargo-messages/darwin-x64'), +// 'win32-x64-msvc': () => require('@cargo-messages/win32-x64-msvc'), +// 'aarch64-pc-windows-msvc': () => require('@cargo-messages/win32-arm64-msvc'), +// 'darwin-x64': () => require('@cargo-messages/darwin-x64'), +// 'darwin-arm64': () => require('@cargo-messages/darwin-arm64'), +// 'linux-x64-gnu': () => require('@cargo-messages/linux-x64-gnu'), +// 'linux-arm-gnueabihf': () => require('@cargo-messages/linux-arm-gnueabihf'), +// 'android-arm-eabi': () => require('@cargo-messages/android-arm-eabi') +// }); + module.exports = require('@neon-rs/load').lazy({ targets: { 'darwin-x64': () => require('@cargo-messages/darwin-x64'), diff --git a/pkgs/load/src/index.ts b/pkgs/load/src/index.ts index 22218b04..1bc28a3a 100644 --- a/pkgs/load/src/index.ts +++ b/pkgs/load/src/index.ts @@ -163,3 +163,73 @@ export function lazy(optionsOrLoaders: LazyOptions | Record any>, ? lazyV1(optionsOrLoaders as Record any>, exports) : lazyV2(optionsOrLoaders as LazyOptions); } + +export function __UNSTABLE_loader(loaders: Record Record>): () => Record { + const target = currentTarget(); + if (!loaders.hasOwnProperty(target)) { + throw new Error(`no precompiled module found for ${target}`); + } + const loader = loaders[target]; + let loaded: Record | null = null; + return () => { + if (loaded) { + return loaded; + } + loaded = loader(); + return loaded; + }; +} + +export function __UNSTABLE_proxy(loaders: Record Record>): any { + const target = currentTarget(); + if (!loaders.hasOwnProperty(target)) { + throw new Error(`no precompiled module found for ${target}`); + } + const loader = loaders[target]; + let loaded: Record | null = null; + + function load(): Record { + if (!loaded) { + loaded = loader(); + } + return loaded; + } + + const handler = { + has(_target: any, key: string) { + return Reflect.has(load(), key); + }, + get(_target: any, key: string) { + return Reflect.get(load(), key); + }, + ownKeys(_target: any) { + return Reflect.ownKeys(load()); + }, + defineProperty(_target: any, _key: string, _descriptor: any) { + throw new Error('attempt to modify read-only Neon module proxy'); + }, + deleteProperty(_target: any, _key: string) { + throw new Error('attempt to modify read-only Neon module proxy'); + }, + set(_target: any, _key: string, _val: any) { + throw new Error('attempt to modify read-only Neon module proxy'); + }, + setPrototypeOf(_target: any, _proto: any) { + throw new Error('attempt to modify read-only Neon module proxy'); + }, + getPrototypeOf(_target: any) { + return Object.getPrototypeOf(load()); + }, + isExtensible(_target: any) { + return Reflect.isExtensible(load()); + }, + preventExtensions(_target: any) { + return Reflect.preventExtensions(load()); + }, + getOwnPropertyDescriptor(_target: any, key: string) { + return Reflect.getOwnPropertyDescriptor(load(), key); + } + }; + + return new Proxy({}, handler); +}