@intersystems-community/ascot 0.0.0-stage → 0.1.0

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.
@@ -0,0 +1,22 @@
1
+ import type { Root } from "../generated/ascot.js" with { "resolution-mode": "import" };
2
+ import type { ClassInfo, RoutineSource } from "../generated/interfaces/iris-ascot-common.js" with { "resolution-mode": "import"
3
+ };
4
+ export type * from "../generated/interfaces/iris-ascot-common.js";
5
+ type RawWorkspace = InstanceType<Root["exported"]["Workspace"]>;
6
+ /** Every method of the wasm `Workspace`, as `createWorkspace` hands it out: all async, since
7
+ * `serialize` below queues each call behind the previous one. */
8
+ export type Workspace = {
9
+ [K in keyof RawWorkspace]: RawWorkspace[K] extends (...args: infer A) => infer R ? (...args: A) => Promise<Awaited<R>> : RawWorkspace[K];
10
+ };
11
+ /** The shape your `imported.iris-connection` implementation must satisfy. */
12
+ export interface Imported {
13
+ getCls(cls: string): Promise<ClassInfo | undefined>;
14
+ getInc(name: string): Promise<RoutineSource | undefined>;
15
+ getIntOrMac(name: string): Promise<RoutineSource | undefined>;
16
+ }
17
+ /**
18
+ * A `Workspace` backed by `imported`, with every method pre-serialized so overlapping
19
+ * calls (e.g. from two documents' diagnostics resolving concurrently) can't trip ascot's
20
+ * internal `RefCell` borrows or jco's single-in-flight-call constraint.
21
+ */
22
+ export declare function createWorkspace(imported: Imported): Promise<Workspace>;
package/dist/index.js ADDED
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createWorkspace = createWorkspace;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ // jco needs the actual `IrisConnection` class (not just an instance) up front, to bind
40
+ // resource-identity checks (`instanceof`) at instantiation time -- so the wasm module is
41
+ // loaded lazily on the first `createWorkspace` call, using that call's own argument's
42
+ // class. Every later call must be constructed from that same class; in practice callers
43
+ // only ever have one `Imported` implementation, so this holds.
44
+ let wasm;
45
+ async function loadWasm(IrisConnection) {
46
+ return (wasm ??= import("../generated/ascot.js").then(({ instantiate }) => instantiate((name) => new WebAssembly.Module(fs.readFileSync(path.resolve(__dirname, "../lib", name))), {
47
+ "iris:ascot/common": {},
48
+ "iris:ascot/imported": { IrisConnection },
49
+ })));
50
+ }
51
+ // jco's jspi glue allows only one in-flight suspended call per component instance --
52
+ // overlapping calls (e.g. diagnostics() and hover() both awaiting a REST round trip)
53
+ // trip its exclusive-lock check. Every `Workspace` this package creates shares the same
54
+ // wasm instance, so this queue is module-wide, not per-Workspace.
55
+ let tail = Promise.resolve();
56
+ function serialize(instance) {
57
+ return new Proxy(instance, {
58
+ get(target, prop, receiver) {
59
+ const value = Reflect.get(target, prop, receiver);
60
+ if (typeof value !== "function")
61
+ return value;
62
+ return async (...args) => {
63
+ const prev = tail;
64
+ let release;
65
+ tail = new Promise((resolve) => (release = resolve));
66
+ await prev;
67
+ try {
68
+ return await value.apply(target, args);
69
+ }
70
+ finally {
71
+ release();
72
+ }
73
+ };
74
+ },
75
+ });
76
+ }
77
+ /**
78
+ * A `Workspace` backed by `imported`, with every method pre-serialized so overlapping
79
+ * calls (e.g. from two documents' diagnostics resolving concurrently) can't trip ascot's
80
+ * internal `RefCell` borrows or jco's single-in-flight-call constraint.
81
+ */
82
+ async function createWorkspace(imported) {
83
+ const IrisConnection = Object.getPrototypeOf(imported).constructor;
84
+ const root = await loadWasm(IrisConnection);
85
+ return serialize(new root.exported.Workspace(imported));
86
+ }
87
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,MAAY,EAAE,oCAAgB;AAC9B,MAAY,IAAI,sCAAkB;AA+BlC,uFAAuF;AACvF,yFAAyF;AACzF,sFAAsF;AACtF,wFAAwF;AACxF,+DAA+D;AAC/D,IAAI,IAA+B,CAAC;AAEpC,KAAK,UAAU,QAAQ,CAAC,cAA2D;IAClF,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CACzE,WAAW,CACV,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAClG;QACC,mBAAmB,EAAE,EAAE;QACvB,qBAAqB,EAAE,EAAE,cAAc,EAAE;KAChC,CACV,CACD,CAAC,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,qFAAqF;AACrF,wFAAwF;AACxF,kEAAkE;AAClE,IAAI,IAAI,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;AAE5C,SAAS,SAAS,CAAC,QAAsB;IACxC,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE;QAC1B,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ;YACzB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YAClD,IAAI,OAAO,KAAK,KAAK,UAAU;gBAAE,OAAO,KAAK,CAAC;YAC9C,OAAO,KAAK,EAAE,GAAG,IAAe,EAAE,EAAE;gBACnC,MAAM,IAAI,GAAG,IAAI,CAAC;gBAClB,IAAI,OAAoB,CAAC;gBACzB,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;gBAC3D,MAAM,IAAI,CAAC;gBACX,IAAI,CAAC;oBACJ,OAAO,MAAM,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACxC,CAAC;wBAAS,CAAC;oBACV,OAAO,EAAE,CAAC;gBACX,CAAC;YACF,CAAC,CAAC;QACH,CAAC;KACD,CAAyB,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACI,KAAK,0BAA0B,QAAkB;IACvD,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC;IACnE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,cAAc,CAAC,CAAC;IAC5C,OAAO,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,43 @@
1
+ // world root:component/root
2
+ import type * as IrisAscotCommon from './interfaces/iris-ascot-common.js'; // iris:ascot/common
3
+ import type * as IrisAscotImported from './interfaces/iris-ascot-imported.js'; // iris:ascot/imported
4
+ import type * as IrisAscotExported from './interfaces/iris-ascot-exported.js'; // iris:ascot/exported
5
+ export interface ImportObject {
6
+ 'iris:ascot/common': typeof IrisAscotCommon,
7
+ 'iris:ascot/imported': typeof IrisAscotImported,
8
+ }
9
+ export interface Root {
10
+ 'iris:ascot/exported': typeof IrisAscotExported,
11
+ exported: typeof IrisAscotExported,
12
+ }
13
+
14
+ /**
15
+ * Instantiates this component with the provided imports and
16
+ * returns a map of all the exports of the component.
17
+ *
18
+ * This function is intended to be similar to the
19
+ * `WebAssembly.Instantiate` constructor. The second `imports`
20
+ * argument is the "import object" for wasm, except here it
21
+ * uses component-model-layer types instead of core wasm
22
+ * integers/numbers/etc.
23
+ *
24
+ * The first argument to this function, `getCoreModule`, is
25
+ * used to compile core wasm modules within the component.
26
+ * Components are composed of core wasm modules and this callback
27
+ * will be invoked per core wasm module. The caller of this
28
+ * function is responsible for reading the core wasm module
29
+ * identified by `path` and returning its compiled
30
+ * `WebAssembly.Module` object. This would use the
31
+ * `WebAssembly.Module` constructor on the web, for example.
32
+ */
33
+ export function instantiate(
34
+ getCoreModule: (path: string) => WebAssembly.Module,
35
+ imports: ImportObject,
36
+ instantiateCore?: (module: WebAssembly.Module, imports: Record<string, any>) => WebAssembly.Instance
37
+ ): Root;
38
+ export function instantiate(
39
+ getCoreModule: (path: string) => WebAssembly.Module | Promise<WebAssembly.Module>,
40
+ imports: ImportObject,
41
+ instantiateCore?: (module: WebAssembly.Module, imports: Record<string, any>) => WebAssembly.Instance | Promise<WebAssembly.Instance>
42
+ ): Root | Promise<Root>;
43
+