@absolutejs/sync 1.7.1 → 1.7.3
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/engine/index.js +73 -24
- package/dist/engine/index.js.map +3 -3
- package/dist/engine/sandbox.d.ts +7 -2
- package/dist/index.js +73 -24
- package/dist/index.js.map +3 -3
- package/package.json +3 -3
package/dist/engine/sandbox.d.ts
CHANGED
|
@@ -60,7 +60,12 @@ export type SandboxConfig = {
|
|
|
60
60
|
};
|
|
61
61
|
/**
|
|
62
62
|
* Build a lazy runner for one mutation's sandboxed source. The first call
|
|
63
|
-
* compiles + spawns; subsequent calls reuse the isolate
|
|
64
|
-
*
|
|
63
|
+
* compiles + spawns; subsequent calls reuse the isolate AND the context
|
|
64
|
+
* (the router Reference is installed once on isolate creation; per-call
|
|
65
|
+
* cost is just two `setGlobal`s for `args` + `ctx`). Calls are serialised
|
|
66
|
+
* via a promise queue so the shared-slot router stays coherent. The
|
|
67
|
+
* context is recycled every {@link DEFAULT_RECYCLE_CONTEXT_AFTER} calls
|
|
68
|
+
* to bound JSC per-call metadata accumulation. If the isolate has been
|
|
69
|
+
* disposed (timeout, memory cap), the next call re-spawns transparently.
|
|
65
70
|
*/
|
|
66
71
|
export declare const makeSandboxedHandler: (source: string, config?: SandboxConfig) => ((args: unknown, ctx: unknown, actions: MutationActions) => Promise<unknown>);
|
package/dist/index.js
CHANGED
|
@@ -725,7 +725,7 @@ var loadIsolatedJsc = async () => {
|
|
|
725
725
|
}
|
|
726
726
|
};
|
|
727
727
|
var wrap = (source) => `
|
|
728
|
-
(
|
|
728
|
+
(() => {
|
|
729
729
|
const userFn = (${source});
|
|
730
730
|
if (typeof userFn !== 'function') {
|
|
731
731
|
throw new Error(
|
|
@@ -734,22 +734,57 @@ var wrap = (source) => `
|
|
|
734
734
|
);
|
|
735
735
|
}
|
|
736
736
|
const actions = {
|
|
737
|
-
insert:
|
|
738
|
-
update:
|
|
739
|
-
delete:
|
|
740
|
-
change:
|
|
737
|
+
insert: (table, data) => __syncAction('insert', table, data),
|
|
738
|
+
update: (table, data) => __syncAction('update', table, data),
|
|
739
|
+
delete: (table, row) => __syncAction('delete', table, row),
|
|
740
|
+
change: (collection, change) => __syncAction('change', collection, change)
|
|
741
741
|
};
|
|
742
|
-
return
|
|
742
|
+
return userFn(args, ctx, actions);
|
|
743
743
|
})()
|
|
744
744
|
`;
|
|
745
|
+
var DEFAULT_RECYCLE_CONTEXT_AFTER = 256;
|
|
746
|
+
var installRouter = async (context, currentActions, Reference) => {
|
|
747
|
+
const router = new Reference((op, ...rest) => {
|
|
748
|
+
const a = currentActions.value;
|
|
749
|
+
if (a === undefined) {
|
|
750
|
+
throw new Error("__syncAction invoked outside an active sandboxed call (shared-slot router)");
|
|
751
|
+
}
|
|
752
|
+
switch (op) {
|
|
753
|
+
case "insert":
|
|
754
|
+
return a.insert(rest[0], rest[1]);
|
|
755
|
+
case "update":
|
|
756
|
+
return a.update(rest[0], rest[1]);
|
|
757
|
+
case "delete":
|
|
758
|
+
return a.delete(rest[0], rest[1]);
|
|
759
|
+
case "change":
|
|
760
|
+
return a.change(rest[0], rest[1]);
|
|
761
|
+
default:
|
|
762
|
+
throw new Error(`unknown sandbox action op: ${String(op)}`);
|
|
763
|
+
}
|
|
764
|
+
});
|
|
765
|
+
await context.setGlobal("__syncAction", router);
|
|
766
|
+
};
|
|
745
767
|
var compile = async (source, config) => {
|
|
746
|
-
const { createIsolate } = await loadIsolatedJsc();
|
|
768
|
+
const { createIsolate, Reference } = await loadIsolatedJsc();
|
|
747
769
|
const isolate = await createIsolate({
|
|
748
770
|
backend: config.backend ?? "auto",
|
|
749
771
|
memoryLimit: config.memoryLimit ?? 32
|
|
750
772
|
});
|
|
751
773
|
const script = await isolate.compileScript(wrap(source));
|
|
752
|
-
|
|
774
|
+
const context = await isolate.createContext();
|
|
775
|
+
const currentActions = {
|
|
776
|
+
value: undefined
|
|
777
|
+
};
|
|
778
|
+
await installRouter(context, currentActions, Reference);
|
|
779
|
+
return {
|
|
780
|
+
context,
|
|
781
|
+
currentActions,
|
|
782
|
+
isolate,
|
|
783
|
+
runQueue: Promise.resolve(undefined),
|
|
784
|
+
script,
|
|
785
|
+
servedCalls: 0,
|
|
786
|
+
timeoutMs: config.timeout ?? 5000
|
|
787
|
+
};
|
|
753
788
|
};
|
|
754
789
|
var makeSandboxedHandler = (source, config = {}) => {
|
|
755
790
|
let pending;
|
|
@@ -763,23 +798,37 @@ var makeSandboxedHandler = (source, config = {}) => {
|
|
|
763
798
|
pending = compile(source, config);
|
|
764
799
|
return pending;
|
|
765
800
|
};
|
|
766
|
-
|
|
801
|
+
const recycleContextIfNeeded = async (compiled) => {
|
|
802
|
+
if (compiled.servedCalls < DEFAULT_RECYCLE_CONTEXT_AFTER)
|
|
803
|
+
return;
|
|
767
804
|
const { Reference } = await loadIsolatedJsc();
|
|
805
|
+
await compiled.context.dispose().catch(() => {});
|
|
806
|
+
compiled.context = await compiled.isolate.createContext();
|
|
807
|
+
await installRouter(compiled.context, compiled.currentActions, Reference);
|
|
808
|
+
compiled.servedCalls = 0;
|
|
809
|
+
};
|
|
810
|
+
return async (args, ctx, actions) => {
|
|
768
811
|
const compiled = await getCompiled();
|
|
769
|
-
const
|
|
770
|
-
|
|
771
|
-
await
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
812
|
+
const prev = compiled.runQueue;
|
|
813
|
+
const turn = prev.then(async () => {
|
|
814
|
+
await recycleContextIfNeeded(compiled);
|
|
815
|
+
compiled.currentActions.value = actions;
|
|
816
|
+
try {
|
|
817
|
+
await compiled.context.setGlobal("args", args);
|
|
818
|
+
await compiled.context.setGlobal("ctx", ctx);
|
|
819
|
+
const result = await compiled.script.run(compiled.context, {
|
|
820
|
+
timeout: compiled.timeoutMs
|
|
821
|
+
});
|
|
822
|
+
return result;
|
|
823
|
+
} finally {
|
|
824
|
+
compiled.currentActions.value = undefined;
|
|
825
|
+
compiled.servedCalls += 1;
|
|
826
|
+
}
|
|
827
|
+
});
|
|
828
|
+
compiled.runQueue = turn.catch(() => {
|
|
829
|
+
return;
|
|
830
|
+
});
|
|
831
|
+
return turn;
|
|
783
832
|
};
|
|
784
833
|
};
|
|
785
834
|
|
|
@@ -2301,5 +2350,5 @@ export {
|
|
|
2301
2350
|
createPresenceHub
|
|
2302
2351
|
};
|
|
2303
2352
|
|
|
2304
|
-
//# debugId=
|
|
2353
|
+
//# debugId=5E4321DCD1FB65A764756E2164756E21
|
|
2305
2354
|
//# sourceMappingURL=index.js.map
|