@intersystems-community/ascot 0.2.0 → 0.3.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.
package/README.md CHANGED
@@ -12,19 +12,10 @@ npm install @intersystems-community/ascot
12
12
 
13
13
  ## Usage
14
14
 
15
- ```ts
16
- import { createWorkspace, type Imported } from "@intersystems-community/ascot";
17
-
18
- // What the engine asks you for when a name isn't defined in the workspace, typically
19
- // answered from an IRIS instance over its REST API. Return `undefined` for "not found",
20
- // or for everything if you have no instance: the workspace is then checked on its own.
21
- class NoIris implements Imported {
22
- async getCls(cls: string) { return undefined; } // a class's members and metadata
23
- async getInc(name: string) { return undefined; } // the text of `name.inc`
24
- async getIntOrMac(name: string) { return undefined; } // the text of routine `name`
25
- }
15
+ ````ts
16
+ import { createWorkspace } from "@intersystems-community/ascot";
26
17
 
27
- const ws = await createWorkspace(new NoIris());
18
+ const ws = await createWorkspace();
28
19
 
29
20
  // `open` is both open and edit: it stores the raw text (the kind comes from the uri's
30
21
  // extension: .cls, .mac, .int, .inc) and returns the uris whose cached analysis is now
@@ -47,12 +38,27 @@ await ws.diagnostics("file:///T.cls");
47
38
 
48
39
  await ws.hover("file:///T.cls", { line: 5, character: 7 }); // the `x` being written
49
40
  // "```objectscript\n%DataType = 1\n```"
41
+ ````
42
+
43
+ To provide declarations for documents that aren't in the workspace, extend `IrisConnection`,
44
+ override the lookups you can answer, and pass an instance:
45
+
46
+ ```ts
47
+ import { IrisConnection, type ClassInfo } from "@intersystems-community/ascot";
48
+
49
+ class MyIris extends IrisConnection {
50
+ override async getCls(cls: string): Promise<ClassInfo | undefined> {
51
+ return undefined; // look `cls` up, e.g. over IRIS's REST API
52
+ }
53
+ }
54
+
55
+ const connected = await createWorkspace(new MyIris());
50
56
  ```
51
57
 
52
58
  `createWorkspace` takes an optional second argument, a `Style` applied to every document:
53
59
 
54
60
  ```ts
55
- const strict = await createWorkspace(new NoIris(), { command: { form: "long" }, function: { case: "pascal" }, commandDo: { form: "short" } });
61
+ const strict = await createWorkspace(undefined, { command: { form: "long" }, function: { case: "pascal" }, commandDo: { form: "short" } });
56
62
  ```
57
63
 
58
64
  Load every file of a project into one `Workspace` so cross-file references resolve, and
@@ -61,30 +67,29 @@ usually not a removal, so keep the on-disk text open instead.
61
67
 
62
68
  ## API
63
69
 
64
- `createWorkspace(imported, style?)` returns a `Workspace` whose methods mirror the engine's
70
+ `createWorkspace(iris?, style?)` returns a `Workspace` whose methods mirror the engine's
65
71
  exports, all returning promises. Positions and ranges are zero-based line/character pairs,
66
72
  as in the Language Server Protocol.
67
73
 
68
- | Method | Returns |
69
- | --- | --- |
70
- | `open(uri, text)` | uris whose analysis is now stale |
71
- | `close(uri)` | uris whose analysis is now stale |
72
- | `diagnostics(uri)` | `Diagnostic[]` |
73
- | `inlayHint(uri, range)` | `InlayHint[]` |
74
- | `definition(uri, position)` | `Location \| undefined` |
75
- | `references(uri, position, includeDeclaration)` | `Location[]` |
76
- | `hover(uri, position)` | markdown `string \| undefined` |
77
- | `documentSymbol(uri)` | the class or routine and its members or labels |
78
- | `workspaceSymbol(query)` | classes and members across the workspace by prefix |
79
- | `queryCls(query)` | `[uri, ClassInfo][]` for classes by prefix |
80
- | `queryMem(cls, query)` | `[uri, MemberInfo][]` for a class's members by prefix |
74
+ | Method | Returns |
75
+ | ----------------------------------------------- | ----------------------------------------------------- |
76
+ | `open(uri, text)` | uris whose analysis is now stale |
77
+ | `close(uri)` | uris whose analysis is now stale |
78
+ | `diagnostics(uri)` | `Diagnostic[]` |
79
+ | `inlayHint(uri, range)` | `InlayHint[]` |
80
+ | `definition(uri, position)` | `Location \| undefined` |
81
+ | `references(uri, position, includeDeclaration)` | `Location[]` |
82
+ | `hover(uri, position)` | markdown `string \| undefined` |
83
+ | `documentSymbol(uri)` | the class or routine and its members or labels |
84
+ | `workspaceSymbol(query)` | classes and members across the workspace by prefix |
85
+ | `queryCls(query)` | `[uri, ClassInfo][]` for classes by prefix |
86
+ | `queryMem(cls, query)` | `[uri, MemberInfo][]` for a class's members by prefix |
81
87
 
82
88
  All result types (`Diagnostic`, `Location`, `ClassInfo`, `MemberInfo`, ...) are exported
83
89
  from the package.
84
90
 
85
- Calls are serialized: one runs at a time, and the rest queue behind it. Every `Workspace`
86
- created by this package shares one wasm instance and one `Imported` class, so construct
87
- them all from the same implementation.
91
+ Calls are serialized: one runs at a time, and the rest queue behind it, across every
92
+ `Workspace` created by this package, since they share one wasm instance.
88
93
 
89
94
  ## Bundling
90
95
 
package/dist/index.d.ts CHANGED
@@ -8,15 +8,19 @@ type RawWorkspace = InstanceType<Root["exported"]["Workspace"]>;
8
8
  export type Workspace = {
9
9
  [K in keyof RawWorkspace]: RawWorkspace[K] extends (...args: infer A) => infer R ? (...args: A) => Promise<Awaited<R>> : RawWorkspace[K];
10
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>;
11
+ export declare class IrisConnection {
12
+ /** A class's own members and metadata. */
13
+ getCls(_cls: string): Promise<ClassInfo | undefined>;
14
+ /** The text of `name.inc`. */
15
+ getInc(_name: string): Promise<RoutineSource | undefined>;
16
+ /** The text of `name.int` or `name.mac`: `{ tag: "none" }` if there is no such routine,
17
+ * `val: undefined` if its source isn't available. */
18
+ getIntOrMac(_name: string): Promise<{
19
+ tag: "none";
20
+ } | {
21
+ tag: "some";
22
+ val: RoutineSource | undefined;
23
+ }>;
16
24
  }
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, style?: Style): Promise<Workspace>;
25
+ /** A workspace whose calls run one at a time, resolving what it doesn't contain through `iris`. */
26
+ export declare function createWorkspace(iris?: IrisConnection, style?: Style): Promise<Workspace>;
package/dist/index.js CHANGED
@@ -33,21 +33,31 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.IrisConnection = void 0;
36
37
  exports.createWorkspace = createWorkspace;
37
38
  const fs = __importStar(require("node:fs"));
38
39
  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
- })));
40
+ class IrisConnection {
41
+ /** A class's own members and metadata. */
42
+ async getCls(_cls) {
43
+ return undefined;
44
+ }
45
+ /** The text of `name.inc`. */
46
+ async getInc(_name) {
47
+ return undefined;
48
+ }
49
+ /** The text of `name.int` or `name.mac`: `{ tag: "none" }` if there is no such routine,
50
+ * `val: undefined` if its source isn't available. */
51
+ async getIntOrMac(_name) {
52
+ return { tag: "some", val: undefined };
53
+ }
50
54
  }
55
+ exports.IrisConnection = IrisConnection;
56
+ const wasm = import("../generated/ascot.js").then(({ instantiate }) => instantiate((name) => new WebAssembly.Module(fs.readFileSync(path.resolve(__dirname, "../lib", name))), {
57
+ "iris:ascot/common": {},
58
+ "iris:ascot/imported": { IrisConnection },
59
+ }));
60
+ wasm.catch(() => { }); // reported by createWorkspace instead
51
61
  // jco's jspi glue allows only one in-flight suspended call per component instance --
52
62
  // overlapping calls (e.g. diagnostics() and hover() both awaiting a REST round trip)
53
63
  // trip its exclusive-lock check. Every `Workspace` this package creates shares the same
@@ -74,14 +84,9 @@ function serialize(instance) {
74
84
  },
75
85
  });
76
86
  }
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, style) {
83
- const IrisConnection = Object.getPrototypeOf(imported).constructor;
84
- const root = await loadWasm(IrisConnection);
85
- return serialize(new root.exported.Workspace(imported, style));
87
+ /** A workspace whose calls run one at a time, resolving what it doesn't contain through `iris`. */
88
+ async function createWorkspace(iris, style) {
89
+ const root = await wasm;
90
+ return serialize(new root.exported.Workspace(iris, style));
86
91
  }
87
92
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +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,EAAE,KAAa;IACtE,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,EAAE,KAAK,CAAC,CAAC,CAAC;AAChE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,MAAY,EAAE,oCAAgB;AAC9B,MAAY,IAAI,sCAAkB;AA4BlC;IACC,0CAA0C;IAC1C,KAAK,CAAC,MAAM,CAAC,IAAY;QACxB,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,8BAA8B;IAC9B,KAAK,CAAC,MAAM,CAAC,KAAa;QACzB,OAAO,SAAS,CAAC;IAClB,CAAC;IACD;yDACqD;IACrD,KAAK,CAAC,WAAW,CAChB,KAAa;QAEb,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;IACxC,CAAC;CACD;;AAED,MAAM,IAAI,GAAkB,MAAM,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CACpF,WAAW,CACV,CAAC,IAAY,EAAE,EAAE,CAChB,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EACjF;IACC,mBAAmB,EAAE,EAAE;IACvB,qBAAqB,EAAE,EAAE,cAAc,EAAE;CAChC,CACV,CACD,CAAC;AACF,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,sCAAsC;AAE5D,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,mGAAmG;AAC5F,KAAK,0BAA0B,IAAqB,EAAE,KAAa;IACzE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IACxB,OAAO,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;AAC5D,CAAC"}