@watchlight/engine 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.
- package/LICENSE +87 -0
- package/README.md +75 -0
- package/index.d.ts +80 -0
- package/index.js +70 -0
- package/package.json +40 -0
- package/wasm/wl_apdp_wasm.d.ts +53 -0
- package/wasm/wl_apdp_wasm.js +431 -0
- package/wasm/wl_apdp_wasm_bg.wasm +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
Watchlight Engine — Developer Edition License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Watchlight AI, LLC. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software, including its compiled artifacts and accompanying files (the
|
|
6
|
+
"Software"), is the proprietary property of Watchlight AI, LLC ("Watchlight").
|
|
7
|
+
The Software is licensed, not sold.
|
|
8
|
+
|
|
9
|
+
1. LICENSE GRANT (Developer Edition)
|
|
10
|
+
|
|
11
|
+
Subject to your compliance with this License, Watchlight grants you a personal,
|
|
12
|
+
non-exclusive, non-transferable, non-sublicensable, royalty-free license to
|
|
13
|
+
download, install, and use the Software — including in production and for
|
|
14
|
+
commercial or revenue-generating purposes — as a component of your own
|
|
15
|
+
applications, agents, or services (the "Permitted Use"). This grant is
|
|
16
|
+
IRREVOCABLE with respect to the version of the Software you have received, so
|
|
17
|
+
long as you comply with Sections 2 and 3; a later version, or the withdrawal of
|
|
18
|
+
future versions, does not affect your right to continue using a version already
|
|
19
|
+
received.
|
|
20
|
+
|
|
21
|
+
2. FREE TIER; WHEN A COMMERCIAL LICENSE IS REQUIRED
|
|
22
|
+
|
|
23
|
+
The Permitted Use is provided free of charge up to the Free Tier limit:
|
|
24
|
+
|
|
25
|
+
Up to twenty-five (25) agents under management per organization, an "agent"
|
|
26
|
+
meaning a distinct governed agent identity. The tier gates on SCALE, not on
|
|
27
|
+
whether the use is production or commercial. A high per-month authorization
|
|
28
|
+
volume ceiling may also apply solely to prevent abuse.
|
|
29
|
+
|
|
30
|
+
A separate written commercial license from Watchlight is required only to:
|
|
31
|
+
|
|
32
|
+
(a) use the Software above the Free Tier limit; or
|
|
33
|
+
(b) provide the Software ITSELF — its authorization decision engine or API —
|
|
34
|
+
to any third party as a standalone hosted, managed, or embedded
|
|
35
|
+
authorization service (i.e. re-offering the Software's functionality as a
|
|
36
|
+
service). Using the Software as an internal component of your own product
|
|
37
|
+
or service, including one you offer to your customers, is Permitted Use
|
|
38
|
+
and does NOT require a separate agreement.
|
|
39
|
+
|
|
40
|
+
Contact legal@watchlight.ai for a commercial license.
|
|
41
|
+
|
|
42
|
+
3. RESTRICTIONS
|
|
43
|
+
|
|
44
|
+
Except as expressly permitted above, and except to the extent applicable law
|
|
45
|
+
prohibits a given restriction, you may NOT, in whole or in part:
|
|
46
|
+
|
|
47
|
+
(a) distribute, publish, sublicense, rent, lease, sell, or otherwise make the
|
|
48
|
+
Software itself available to any third party as the Software (deploying it
|
|
49
|
+
within your own application or service as permitted in Section 1 is not a
|
|
50
|
+
distribution of the Software);
|
|
51
|
+
(b) modify, adapt, translate, or create derivative works of the Software;
|
|
52
|
+
(c) decompile, disassemble, reverse engineer, or otherwise attempt to derive
|
|
53
|
+
the source code, structure, or underlying ideas of the Software;
|
|
54
|
+
(d) remove, obscure, or alter any proprietary notices in the Software; or
|
|
55
|
+
(e) use the Software outside the scope of the Permitted Use.
|
|
56
|
+
|
|
57
|
+
4. RESERVATION OF RIGHTS
|
|
58
|
+
|
|
59
|
+
Watchlight reserves all rights not expressly granted. No rights are granted by
|
|
60
|
+
implication, estoppel, or otherwise. The Software is licensed, not sold, and
|
|
61
|
+
Watchlight retains all right, title, and interest in and to the Software.
|
|
62
|
+
|
|
63
|
+
5. TERMINATION
|
|
64
|
+
|
|
65
|
+
If you breach this License, Watchlight will provide written notice and a period
|
|
66
|
+
of thirty (30) days to cure the breach. If the breach is cured within that
|
|
67
|
+
period, this License continues uninterrupted. If it is not cured, this License
|
|
68
|
+
terminates at the end of the cure period, and you must then cease all use of the
|
|
69
|
+
Software and destroy all copies in your possession or control. To avoid
|
|
70
|
+
disrupting a live authorization path, termination for a curable breach never
|
|
71
|
+
takes effect before the cure period ends. Sections 3, 4, 6, and 7 survive
|
|
72
|
+
termination.
|
|
73
|
+
|
|
74
|
+
6. DISCLAIMER OF WARRANTY
|
|
75
|
+
|
|
76
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
77
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
78
|
+
FOR A PARTICULAR PURPOSE, TITLE, AND NONINFRINGEMENT.
|
|
79
|
+
|
|
80
|
+
7. LIMITATION OF LIABILITY
|
|
81
|
+
|
|
82
|
+
IN NO EVENT SHALL WATCHLIGHT AI, LLC BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
|
|
83
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM,
|
|
84
|
+
OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
85
|
+
SOFTWARE.
|
|
86
|
+
|
|
87
|
+
For licensing inquiries, contact: legal@watchlight.ai
|
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# @watchlight/engine
|
|
2
|
+
|
|
3
|
+
The Watchlight **Developer Edition** authorization engine for Node — the real
|
|
4
|
+
`wl-apdp` Cedar pipeline (delegation → intent → goal → policy selection → Cedar
|
|
5
|
+
→ strict-subset sub-agent attenuation → enforcement effects) compiled to
|
|
6
|
+
WebAssembly. In-process, fail-closed, zero infrastructure.
|
|
7
|
+
|
|
8
|
+
This is the **same authorization core** as the Python engine
|
|
9
|
+
([`watchlight-engine`](https://pypi.org/project/watchlight-engine/)) — a
|
|
10
|
+
conformance test asserts both bindings return identical decisions for identical
|
|
11
|
+
inputs. No sidecar, no network, no policy re-implementation in JS.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @watchlight/engine
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Node ≥ 18 (uses WebAssembly bulk-memory + Web Crypto, both stable there).
|
|
20
|
+
|
|
21
|
+
## Use
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
const { Engine } = require("@watchlight/engine");
|
|
25
|
+
|
|
26
|
+
const engine = await Engine.create();
|
|
27
|
+
|
|
28
|
+
await engine.addPolicy({
|
|
29
|
+
name: "allow-read",
|
|
30
|
+
code: 'permit(principal, action == Action::"read", resource);',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Authorize — context defaults to {}. Fail-closed: unmatched → Deny.
|
|
34
|
+
const resp = await engine.authorize({
|
|
35
|
+
principal: 'User::"alice"',
|
|
36
|
+
action: 'Action::"read"',
|
|
37
|
+
resource: 'Document::"doc1"',
|
|
38
|
+
});
|
|
39
|
+
console.log(resp.decision); // "Allow"
|
|
40
|
+
|
|
41
|
+
// Strict-subset sub-agent scope attenuation (synchronous).
|
|
42
|
+
const atten = engine.attenuateScope(
|
|
43
|
+
{ allowed_tools: ["read", "search"], allowed_resources: [], allowed_intents: [], max_depth: 5, time_budget_seconds: 600, depth: 0 },
|
|
44
|
+
{ allowed_tools: ["read"], allowed_resources: [], allowed_intents: [], max_depth: 2, time_budget_seconds: 300 }
|
|
45
|
+
);
|
|
46
|
+
console.log(atten.decision); // "Allow" (child ⊆ parent) — a superset would Deny
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`authorize` / `addPolicy` are async (the engine's pipeline is async;
|
|
50
|
+
WebAssembly has no blocking wait, so they return Promises). `attenuateScope`
|
|
51
|
+
is synchronous. TypeScript types ship in `index.d.ts`.
|
|
52
|
+
|
|
53
|
+
## Graduation to Enterprise
|
|
54
|
+
|
|
55
|
+
The same code moves to the networked Watchlight control plane (signed lineage,
|
|
56
|
+
cross-tenant isolation, IdP/mTLS attestation) by pointing at it — your policies
|
|
57
|
+
and call sites do not change.
|
|
58
|
+
|
|
59
|
+
## Build from source
|
|
60
|
+
|
|
61
|
+
Requires the `wasm32-unknown-unknown` target, [`wasm-pack`](https://rustwasm.github.io/wasm-pack/),
|
|
62
|
+
and (optionally, for a smaller artifact) a modern [`binaryen`](https://github.com/WebAssembly/binaryen) `wasm-opt`:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
rustup target add wasm32-unknown-unknown
|
|
66
|
+
npm run build # → ./wasm (regenerated; not committed)
|
|
67
|
+
npm test # Node conformance (7/7)
|
|
68
|
+
npm run conformance # Node + Python parity (needs: pip install watchlight-engine)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
Watchlight Engine — Developer Edition License (see `LICENSE`). Free for
|
|
74
|
+
development, testing, **and production**, including commercially, for up to 25
|
|
75
|
+
governed agents per organization.
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Type definitions for @watchlight/engine
|
|
2
|
+
|
|
3
|
+
/** A Cedar policy to load into the engine. At minimum `{ name, code }`. */
|
|
4
|
+
export interface PolicyInput {
|
|
5
|
+
name: string;
|
|
6
|
+
/** Cedar policy source. */
|
|
7
|
+
code: string;
|
|
8
|
+
id?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
active?: boolean;
|
|
11
|
+
[k: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** An authorization request. At minimum `{ principal, action, resource }`. */
|
|
15
|
+
export interface AuthorizationRequest {
|
|
16
|
+
principal: string;
|
|
17
|
+
action: string;
|
|
18
|
+
resource: string;
|
|
19
|
+
/** Defaults to `{}` when omitted. */
|
|
20
|
+
context?: Record<string, unknown>;
|
|
21
|
+
intent?: string;
|
|
22
|
+
execution_id?: string;
|
|
23
|
+
[k: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** The engine's decision. Fail-closed: an unmatched request is `"Deny"`. */
|
|
27
|
+
export interface AuthorizationResponse {
|
|
28
|
+
decision: "Allow" | "Deny" | string;
|
|
29
|
+
reason?: string;
|
|
30
|
+
details?: Record<string, unknown>;
|
|
31
|
+
[k: string]: unknown;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** A parent's granted sub-agent scope. */
|
|
35
|
+
export interface GrantedScope {
|
|
36
|
+
allowed_tools: string[];
|
|
37
|
+
allowed_resources: { matcher: string }[];
|
|
38
|
+
allowed_intents: string[];
|
|
39
|
+
max_depth: number;
|
|
40
|
+
time_budget_seconds: number;
|
|
41
|
+
depth?: number;
|
|
42
|
+
deadline?: string | null;
|
|
43
|
+
parent_run_handle_id?: string | null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** A requested child sub-agent scope. */
|
|
47
|
+
export interface RequestedScope {
|
|
48
|
+
allowed_tools: string[];
|
|
49
|
+
allowed_resources: { matcher: string }[];
|
|
50
|
+
allowed_intents: string[];
|
|
51
|
+
max_depth: number;
|
|
52
|
+
time_budget_seconds: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Result of `attenuateScope`. */
|
|
56
|
+
export type AttenuationResult =
|
|
57
|
+
| { decision: "Allow"; granted_scope: GrantedScope }
|
|
58
|
+
| { decision: "Deny"; reason: string; violations: string[] };
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* In-process Watchlight policy engine — the real wl-apdp Cedar pipeline over
|
|
62
|
+
* in-memory storage, compiled to WebAssembly. Fail-closed.
|
|
63
|
+
*/
|
|
64
|
+
export class Engine {
|
|
65
|
+
private constructor(inner: unknown);
|
|
66
|
+
/** Construct the engine. */
|
|
67
|
+
static create(): Promise<Engine>;
|
|
68
|
+
/** Load a Cedar policy. */
|
|
69
|
+
addPolicy(policy: PolicyInput | string): Promise<void>;
|
|
70
|
+
/** Authorize a request; `context` defaults to `{}`. */
|
|
71
|
+
authorize(request: AuthorizationRequest | string): Promise<AuthorizationResponse>;
|
|
72
|
+
/** Attenuate a child scope against a parent's granted scope (synchronous). */
|
|
73
|
+
attenuateScope(
|
|
74
|
+
parentScope: GrantedScope | string,
|
|
75
|
+
requestedScope: RequestedScope | string
|
|
76
|
+
): AttenuationResult;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** The compiled engine version. */
|
|
80
|
+
export function version(): string;
|
package/index.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// @watchlight/engine — ergonomic wrapper over the wasm-bindgen bindings for the
|
|
2
|
+
// real wl-apdp authorization core. Mirrors the Developer-Edition Python
|
|
3
|
+
// `PolicyEngine` API (create → addPolicy → authorize / attenuateScope), returns
|
|
4
|
+
// parsed JS objects, and defaults `context` to `{}` so callers never hand-write
|
|
5
|
+
// it. Fail-closed throughout — an unmatched request denies.
|
|
6
|
+
//
|
|
7
|
+
// The heavy lifting (Cedar eval, attenuation, enforcement effects) is the
|
|
8
|
+
// compiled wasm core; this file is glue only, no decision logic.
|
|
9
|
+
|
|
10
|
+
const wasm = require("./wasm/wl_apdp_wasm.js");
|
|
11
|
+
|
|
12
|
+
const asJson = (v) => (typeof v === "string" ? v : JSON.stringify(v));
|
|
13
|
+
|
|
14
|
+
/** In-process Watchlight policy engine (real wl-apdp core over in-memory storage). */
|
|
15
|
+
class Engine {
|
|
16
|
+
/** @param {import("./wasm/wl_apdp_wasm").PolicyEngine} inner */
|
|
17
|
+
constructor(inner) {
|
|
18
|
+
/** @private */
|
|
19
|
+
this._inner = inner;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Construct the engine. `const engine = await Engine.create();` */
|
|
23
|
+
static async create() {
|
|
24
|
+
const inner = await wasm.PolicyEngine.create();
|
|
25
|
+
return new Engine(inner);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Load a Cedar policy. Accepts an object or JSON string; at minimum
|
|
30
|
+
* `{ name, code }` (Cedar source). id/active/timestamps are defaulted.
|
|
31
|
+
* @param {object|string} policy
|
|
32
|
+
* @returns {Promise<void>}
|
|
33
|
+
*/
|
|
34
|
+
addPolicy(policy) {
|
|
35
|
+
return this._inner.addPolicy(asJson(policy));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Authorize a request. Accepts an object or JSON string; at minimum
|
|
40
|
+
* `{ principal, action, resource }`. `context` defaults to `{}`.
|
|
41
|
+
* Resolves to the parsed AuthorizationResponse (`decision`, `reason`,
|
|
42
|
+
* `details`, ...). Fail-closed: unmatched → `decision: "Deny"`.
|
|
43
|
+
* @param {object|string} request
|
|
44
|
+
* @returns {Promise<object>}
|
|
45
|
+
*/
|
|
46
|
+
async authorize(request) {
|
|
47
|
+
let req = request;
|
|
48
|
+
if (req && typeof req === "object" && req.context === undefined) {
|
|
49
|
+
req = { ...req, context: {} };
|
|
50
|
+
}
|
|
51
|
+
const raw = await this._inner.authorize(asJson(req));
|
|
52
|
+
return JSON.parse(raw);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Attenuate a requested sub-agent scope against a parent's granted scope
|
|
57
|
+
* (strict-subset validator). Synchronous. Returns the parsed result:
|
|
58
|
+
* `{ decision: "Allow", granted_scope }` or `{ decision: "Deny", reason,
|
|
59
|
+
* violations }`. Fail-closed.
|
|
60
|
+
* @param {object|string} parentScope
|
|
61
|
+
* @param {object|string} requestedScope
|
|
62
|
+
* @returns {object}
|
|
63
|
+
*/
|
|
64
|
+
attenuateScope(parentScope, requestedScope) {
|
|
65
|
+
const raw = this._inner.attenuateScope(asJson(parentScope), asJson(requestedScope));
|
|
66
|
+
return JSON.parse(raw);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = { Engine, version: wasm.version };
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@watchlight/engine",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Watchlight Developer Edition authorization engine for Node — the real wl-apdp Cedar pipeline (delegation → intent → goal → policy selection → Cedar → strict-subset attenuation → enforcement effects) compiled to WebAssembly. In-process, fail-closed, zero infrastructure.",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "./index.js",
|
|
7
|
+
"types": "./index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"index.js",
|
|
10
|
+
"index.d.ts",
|
|
11
|
+
"wasm/wl_apdp_wasm.js",
|
|
12
|
+
"wasm/wl_apdp_wasm_bg.wasm",
|
|
13
|
+
"wasm/wl_apdp_wasm.d.ts",
|
|
14
|
+
"LICENSE",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=18"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "./build.sh",
|
|
22
|
+
"test": "node conformance/run_node.mjs",
|
|
23
|
+
"conformance": "node conformance/run_node.mjs && python3 conformance/run_python.py",
|
|
24
|
+
"prepublishOnly": "./build.sh"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"authorization",
|
|
28
|
+
"cedar",
|
|
29
|
+
"policy",
|
|
30
|
+
"agent",
|
|
31
|
+
"governance",
|
|
32
|
+
"wasm",
|
|
33
|
+
"watchlight"
|
|
34
|
+
],
|
|
35
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
36
|
+
"homepage": "https://www.watchlight.ai",
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The in-process Watchlight policy engine, exposed to JS.
|
|
6
|
+
*
|
|
7
|
+
* Wraps the real wl-apdp `AuthzService` over in-memory storage. `Rc` (not
|
|
8
|
+
* `Arc`) because wasm is single-threaded; each async method clones the handle
|
|
9
|
+
* into a `'static` future so the returned Promise never borrows `self`.
|
|
10
|
+
*/
|
|
11
|
+
export class PolicyEngine {
|
|
12
|
+
private constructor();
|
|
13
|
+
free(): void;
|
|
14
|
+
[Symbol.dispose](): void;
|
|
15
|
+
/**
|
|
16
|
+
* Load a Cedar policy. `policy_json` is the wl-apdp [`Policy`] shape — at
|
|
17
|
+
* minimum `{"name": ..., "code": "<cedar>"}`. `id`/`active`/timestamps are
|
|
18
|
+
* defaulted so a developer never hand-writes them (mirrors the PyO3
|
|
19
|
+
* binding). Runs the REAL validation + load path.
|
|
20
|
+
*/
|
|
21
|
+
addPolicy(policy_json: string): Promise<any>;
|
|
22
|
+
/**
|
|
23
|
+
* Attenuate a requested sub-agent scope against a parent's granted scope
|
|
24
|
+
* via the REAL strict-subset validator (M43-C `validate_strict_subset`).
|
|
25
|
+
* Synchronous — the validator does no I/O. Returns a JSON string:
|
|
26
|
+
* `{"decision":"Allow","granted_scope":{...}}` or
|
|
27
|
+
* `{"decision":"Deny","reason":"...","violations":[...]}`. Fail-closed.
|
|
28
|
+
*
|
|
29
|
+
* Developer-Edition simplification (identical to the PyO3 binding):
|
|
30
|
+
* single-tenant and no tenant time-budget ceiling — cross-tenant isolation
|
|
31
|
+
* and tenant-budget clamps are the Enterprise control plane's concern.
|
|
32
|
+
*/
|
|
33
|
+
attenuateScope(parent_scope_json: string, requested_scope_json: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Authorize a request; resolves to the [`AuthorizationResponse`] JSON
|
|
36
|
+
* string (`decision`, `reason`, `details`, ...). Drives the FULL
|
|
37
|
+
* production pipeline in-process and is fail-closed: an unmatched request
|
|
38
|
+
* denies. JS: `const resp = JSON.parse(await engine.authorize(reqJson));`.
|
|
39
|
+
*/
|
|
40
|
+
authorize(request_json: string): Promise<any>;
|
|
41
|
+
/**
|
|
42
|
+
* Build an in-process engine over in-memory storage (no Postgres, no
|
|
43
|
+
* network). Async because `AuthzService::new` is async — JS calls it as
|
|
44
|
+
* `const engine = await PolicyEngine.create();`.
|
|
45
|
+
*/
|
|
46
|
+
static create(): Promise<any>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The crate version — a trivial smoke function to confirm the module loads and
|
|
51
|
+
* the real core linked.
|
|
52
|
+
*/
|
|
53
|
+
export function version(): string;
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
/* @ts-self-types="./wl_apdp_wasm.d.ts" */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The in-process Watchlight policy engine, exposed to JS.
|
|
5
|
+
*
|
|
6
|
+
* Wraps the real wl-apdp `AuthzService` over in-memory storage. `Rc` (not
|
|
7
|
+
* `Arc`) because wasm is single-threaded; each async method clones the handle
|
|
8
|
+
* into a `'static` future so the returned Promise never borrows `self`.
|
|
9
|
+
*/
|
|
10
|
+
class PolicyEngine {
|
|
11
|
+
static __wrap(ptr) {
|
|
12
|
+
const obj = Object.create(PolicyEngine.prototype);
|
|
13
|
+
obj.__wbg_ptr = ptr;
|
|
14
|
+
PolicyEngineFinalization.register(obj, obj.__wbg_ptr, obj);
|
|
15
|
+
return obj;
|
|
16
|
+
}
|
|
17
|
+
__destroy_into_raw() {
|
|
18
|
+
const ptr = this.__wbg_ptr;
|
|
19
|
+
this.__wbg_ptr = 0;
|
|
20
|
+
PolicyEngineFinalization.unregister(this);
|
|
21
|
+
return ptr;
|
|
22
|
+
}
|
|
23
|
+
free() {
|
|
24
|
+
const ptr = this.__destroy_into_raw();
|
|
25
|
+
wasm.__wbg_policyengine_free(ptr, 0);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Load a Cedar policy. `policy_json` is the wl-apdp [`Policy`] shape — at
|
|
29
|
+
* minimum `{"name": ..., "code": "<cedar>"}`. `id`/`active`/timestamps are
|
|
30
|
+
* defaulted so a developer never hand-writes them (mirrors the PyO3
|
|
31
|
+
* binding). Runs the REAL validation + load path.
|
|
32
|
+
* @param {string} policy_json
|
|
33
|
+
* @returns {Promise<any>}
|
|
34
|
+
*/
|
|
35
|
+
addPolicy(policy_json) {
|
|
36
|
+
const ptr0 = passStringToWasm0(policy_json, wasm.__wbindgen_export3, wasm.__wbindgen_export4);
|
|
37
|
+
const len0 = WASM_VECTOR_LEN;
|
|
38
|
+
const ret = wasm.policyengine_addPolicy(this.__wbg_ptr, ptr0, len0);
|
|
39
|
+
return takeObject(ret);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Attenuate a requested sub-agent scope against a parent's granted scope
|
|
43
|
+
* via the REAL strict-subset validator (M43-C `validate_strict_subset`).
|
|
44
|
+
* Synchronous — the validator does no I/O. Returns a JSON string:
|
|
45
|
+
* `{"decision":"Allow","granted_scope":{...}}` or
|
|
46
|
+
* `{"decision":"Deny","reason":"...","violations":[...]}`. Fail-closed.
|
|
47
|
+
*
|
|
48
|
+
* Developer-Edition simplification (identical to the PyO3 binding):
|
|
49
|
+
* single-tenant and no tenant time-budget ceiling — cross-tenant isolation
|
|
50
|
+
* and tenant-budget clamps are the Enterprise control plane's concern.
|
|
51
|
+
* @param {string} parent_scope_json
|
|
52
|
+
* @param {string} requested_scope_json
|
|
53
|
+
* @returns {string}
|
|
54
|
+
*/
|
|
55
|
+
attenuateScope(parent_scope_json, requested_scope_json) {
|
|
56
|
+
let deferred4_0;
|
|
57
|
+
let deferred4_1;
|
|
58
|
+
try {
|
|
59
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
60
|
+
const ptr0 = passStringToWasm0(parent_scope_json, wasm.__wbindgen_export3, wasm.__wbindgen_export4);
|
|
61
|
+
const len0 = WASM_VECTOR_LEN;
|
|
62
|
+
const ptr1 = passStringToWasm0(requested_scope_json, wasm.__wbindgen_export3, wasm.__wbindgen_export4);
|
|
63
|
+
const len1 = WASM_VECTOR_LEN;
|
|
64
|
+
wasm.policyengine_attenuateScope(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1);
|
|
65
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
66
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
67
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
68
|
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
|
69
|
+
var ptr3 = r0;
|
|
70
|
+
var len3 = r1;
|
|
71
|
+
if (r3) {
|
|
72
|
+
ptr3 = 0; len3 = 0;
|
|
73
|
+
throw takeObject(r2);
|
|
74
|
+
}
|
|
75
|
+
deferred4_0 = ptr3;
|
|
76
|
+
deferred4_1 = len3;
|
|
77
|
+
return getStringFromWasm0(ptr3, len3);
|
|
78
|
+
} finally {
|
|
79
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
80
|
+
wasm.__wbindgen_export5(deferred4_0, deferred4_1, 1);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Authorize a request; resolves to the [`AuthorizationResponse`] JSON
|
|
85
|
+
* string (`decision`, `reason`, `details`, ...). Drives the FULL
|
|
86
|
+
* production pipeline in-process and is fail-closed: an unmatched request
|
|
87
|
+
* denies. JS: `const resp = JSON.parse(await engine.authorize(reqJson));`.
|
|
88
|
+
* @param {string} request_json
|
|
89
|
+
* @returns {Promise<any>}
|
|
90
|
+
*/
|
|
91
|
+
authorize(request_json) {
|
|
92
|
+
const ptr0 = passStringToWasm0(request_json, wasm.__wbindgen_export3, wasm.__wbindgen_export4);
|
|
93
|
+
const len0 = WASM_VECTOR_LEN;
|
|
94
|
+
const ret = wasm.policyengine_authorize(this.__wbg_ptr, ptr0, len0);
|
|
95
|
+
return takeObject(ret);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Build an in-process engine over in-memory storage (no Postgres, no
|
|
99
|
+
* network). Async because `AuthzService::new` is async — JS calls it as
|
|
100
|
+
* `const engine = await PolicyEngine.create();`.
|
|
101
|
+
* @returns {Promise<any>}
|
|
102
|
+
*/
|
|
103
|
+
static create() {
|
|
104
|
+
const ret = wasm.policyengine_create();
|
|
105
|
+
return takeObject(ret);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (Symbol.dispose) PolicyEngine.prototype[Symbol.dispose] = PolicyEngine.prototype.free;
|
|
109
|
+
exports.PolicyEngine = PolicyEngine;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The crate version — a trivial smoke function to confirm the module loads and
|
|
113
|
+
* the real core linked.
|
|
114
|
+
* @returns {string}
|
|
115
|
+
*/
|
|
116
|
+
function version() {
|
|
117
|
+
let deferred1_0;
|
|
118
|
+
let deferred1_1;
|
|
119
|
+
try {
|
|
120
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
121
|
+
wasm.version(retptr);
|
|
122
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
123
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
124
|
+
deferred1_0 = r0;
|
|
125
|
+
deferred1_1 = r1;
|
|
126
|
+
return getStringFromWasm0(r0, r1);
|
|
127
|
+
} finally {
|
|
128
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
129
|
+
wasm.__wbindgen_export5(deferred1_0, deferred1_1, 1);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
exports.version = version;
|
|
133
|
+
function __wbg_get_imports() {
|
|
134
|
+
const import0 = {
|
|
135
|
+
__proto__: null,
|
|
136
|
+
__wbg___wbindgen_is_function_5e4570eb24ffa122: function(arg0) {
|
|
137
|
+
const ret = typeof(getObject(arg0)) === 'function';
|
|
138
|
+
return ret;
|
|
139
|
+
},
|
|
140
|
+
__wbg___wbindgen_is_undefined_6cff064c44e0d823: function(arg0) {
|
|
141
|
+
const ret = getObject(arg0) === undefined;
|
|
142
|
+
return ret;
|
|
143
|
+
},
|
|
144
|
+
__wbg___wbindgen_throw_bb96b2010945f0bc: function(arg0, arg1) {
|
|
145
|
+
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
146
|
+
},
|
|
147
|
+
__wbg__wbg_cb_unref_be22cc64ae6946a0: function(arg0) {
|
|
148
|
+
getObject(arg0)._wbg_cb_unref();
|
|
149
|
+
},
|
|
150
|
+
__wbg_call_35dba3c747ad7521: function() { return handleError(function (arg0, arg1, arg2) {
|
|
151
|
+
const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
|
|
152
|
+
return addHeapObject(ret);
|
|
153
|
+
}, arguments); },
|
|
154
|
+
__wbg_getRandomValues_26c0cdf963e46393: function() { return handleError(function (arg0, arg1) {
|
|
155
|
+
globalThis.crypto.getRandomValues(getArrayU8FromWasm0(arg0, arg1));
|
|
156
|
+
}, arguments); },
|
|
157
|
+
__wbg_getTime_63fb0332e6c4ec17: function(arg0) {
|
|
158
|
+
const ret = getObject(arg0).getTime();
|
|
159
|
+
return ret;
|
|
160
|
+
},
|
|
161
|
+
__wbg_new_0_f117d868b403dc07: function() {
|
|
162
|
+
const ret = new Date();
|
|
163
|
+
return addHeapObject(ret);
|
|
164
|
+
},
|
|
165
|
+
__wbg_new_typed_cceaf62d8d95e9f2: function(arg0, arg1) {
|
|
166
|
+
try {
|
|
167
|
+
var state0 = {a: arg0, b: arg1};
|
|
168
|
+
var cb0 = (arg0, arg1) => {
|
|
169
|
+
const a = state0.a;
|
|
170
|
+
state0.a = 0;
|
|
171
|
+
try {
|
|
172
|
+
return __wasm_bindgen_func_elem_3775(a, state0.b, arg0, arg1);
|
|
173
|
+
} finally {
|
|
174
|
+
state0.a = a;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
const ret = new Promise(cb0);
|
|
178
|
+
return addHeapObject(ret);
|
|
179
|
+
} finally {
|
|
180
|
+
state0.a = 0;
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
__wbg_now_e7c6795a7f81e10f: function(arg0) {
|
|
184
|
+
const ret = getObject(arg0).now();
|
|
185
|
+
return ret;
|
|
186
|
+
},
|
|
187
|
+
__wbg_performance_3fcf6e32a7e1ed0a: function(arg0) {
|
|
188
|
+
const ret = getObject(arg0).performance;
|
|
189
|
+
return addHeapObject(ret);
|
|
190
|
+
},
|
|
191
|
+
__wbg_policyengine_new: function(arg0) {
|
|
192
|
+
const ret = PolicyEngine.__wrap(arg0);
|
|
193
|
+
return addHeapObject(ret);
|
|
194
|
+
},
|
|
195
|
+
__wbg_queueMicrotask_ac694eae12e92dfb: function(arg0) {
|
|
196
|
+
queueMicrotask(getObject(arg0));
|
|
197
|
+
},
|
|
198
|
+
__wbg_queueMicrotask_be5fe34a8f4cad4d: function(arg0) {
|
|
199
|
+
const ret = getObject(arg0).queueMicrotask;
|
|
200
|
+
return addHeapObject(ret);
|
|
201
|
+
},
|
|
202
|
+
__wbg_resolve_020f95d838c6ef25: function(arg0) {
|
|
203
|
+
const ret = Promise.resolve(getObject(arg0));
|
|
204
|
+
return addHeapObject(ret);
|
|
205
|
+
},
|
|
206
|
+
__wbg_static_accessor_GLOBAL_THIS_466428f93b4eaa76: function() {
|
|
207
|
+
const ret = typeof globalThis === 'undefined' ? null : globalThis;
|
|
208
|
+
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
209
|
+
},
|
|
210
|
+
__wbg_static_accessor_GLOBAL_c7aea38d4de089bc: function() {
|
|
211
|
+
const ret = typeof global === 'undefined' ? null : global;
|
|
212
|
+
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
213
|
+
},
|
|
214
|
+
__wbg_static_accessor_SELF_42d4fae05e59267a: function() {
|
|
215
|
+
const ret = typeof self === 'undefined' ? null : self;
|
|
216
|
+
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
217
|
+
},
|
|
218
|
+
__wbg_static_accessor_WINDOW_e0db14a0eba6a812: function() {
|
|
219
|
+
const ret = typeof window === 'undefined' ? null : window;
|
|
220
|
+
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
221
|
+
},
|
|
222
|
+
__wbg_then_7026b513a94278a8: function(arg0, arg1) {
|
|
223
|
+
const ret = getObject(arg0).then(getObject(arg1));
|
|
224
|
+
return addHeapObject(ret);
|
|
225
|
+
},
|
|
226
|
+
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
|
227
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 477, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
|
228
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_3744);
|
|
229
|
+
return addHeapObject(ret);
|
|
230
|
+
},
|
|
231
|
+
__wbindgen_cast_0000000000000002: function(arg0, arg1) {
|
|
232
|
+
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
233
|
+
const ret = getStringFromWasm0(arg0, arg1);
|
|
234
|
+
return addHeapObject(ret);
|
|
235
|
+
},
|
|
236
|
+
__wbindgen_object_clone_ref: function(arg0) {
|
|
237
|
+
const ret = getObject(arg0);
|
|
238
|
+
return addHeapObject(ret);
|
|
239
|
+
},
|
|
240
|
+
__wbindgen_object_drop_ref: function(arg0) {
|
|
241
|
+
takeObject(arg0);
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
return {
|
|
245
|
+
__proto__: null,
|
|
246
|
+
"./wl_apdp_wasm_bg.js": import0,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function __wasm_bindgen_func_elem_3744(arg0, arg1, arg2) {
|
|
251
|
+
try {
|
|
252
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
253
|
+
wasm.__wasm_bindgen_func_elem_3744(retptr, arg0, arg1, addHeapObject(arg2));
|
|
254
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
255
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
256
|
+
if (r1) {
|
|
257
|
+
throw takeObject(r0);
|
|
258
|
+
}
|
|
259
|
+
} finally {
|
|
260
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function __wasm_bindgen_func_elem_3775(arg0, arg1, arg2, arg3) {
|
|
265
|
+
wasm.__wasm_bindgen_func_elem_3775(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const PolicyEngineFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
269
|
+
? { register: () => {}, unregister: () => {} }
|
|
270
|
+
: new FinalizationRegistry(ptr => wasm.__wbg_policyengine_free(ptr, 1));
|
|
271
|
+
|
|
272
|
+
function addHeapObject(obj) {
|
|
273
|
+
if (heap_next === heap.length) heap.push(heap.length + 1);
|
|
274
|
+
const idx = heap_next;
|
|
275
|
+
heap_next = heap[idx];
|
|
276
|
+
|
|
277
|
+
heap[idx] = obj;
|
|
278
|
+
return idx;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const CLOSURE_DTORS = (typeof FinalizationRegistry === 'undefined')
|
|
282
|
+
? { register: () => {}, unregister: () => {} }
|
|
283
|
+
: new FinalizationRegistry(state => wasm.__wbindgen_export2(state.a, state.b));
|
|
284
|
+
|
|
285
|
+
function dropObject(idx) {
|
|
286
|
+
if (idx < 1028) return;
|
|
287
|
+
heap[idx] = heap_next;
|
|
288
|
+
heap_next = idx;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function getArrayU8FromWasm0(ptr, len) {
|
|
292
|
+
ptr = ptr >>> 0;
|
|
293
|
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
let cachedDataViewMemory0 = null;
|
|
297
|
+
function getDataViewMemory0() {
|
|
298
|
+
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
|
|
299
|
+
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
|
|
300
|
+
}
|
|
301
|
+
return cachedDataViewMemory0;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function getStringFromWasm0(ptr, len) {
|
|
305
|
+
return decodeText(ptr >>> 0, len);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
let cachedUint8ArrayMemory0 = null;
|
|
309
|
+
function getUint8ArrayMemory0() {
|
|
310
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
311
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
312
|
+
}
|
|
313
|
+
return cachedUint8ArrayMemory0;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function getObject(idx) { return heap[idx]; }
|
|
317
|
+
|
|
318
|
+
function handleError(f, args) {
|
|
319
|
+
try {
|
|
320
|
+
return f.apply(this, args);
|
|
321
|
+
} catch (e) {
|
|
322
|
+
wasm.__wbindgen_export(addHeapObject(e));
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
let heap = new Array(1024).fill(undefined);
|
|
327
|
+
heap.push(undefined, null, true, false);
|
|
328
|
+
|
|
329
|
+
let heap_next = heap.length;
|
|
330
|
+
|
|
331
|
+
function isLikeNone(x) {
|
|
332
|
+
return x === undefined || x === null;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function makeMutClosure(arg0, arg1, f) {
|
|
336
|
+
const state = { a: arg0, b: arg1, cnt: 1 };
|
|
337
|
+
const real = (...args) => {
|
|
338
|
+
|
|
339
|
+
// First up with a closure we increment the internal reference
|
|
340
|
+
// count. This ensures that the Rust closure environment won't
|
|
341
|
+
// be deallocated while we're invoking it.
|
|
342
|
+
state.cnt++;
|
|
343
|
+
const a = state.a;
|
|
344
|
+
state.a = 0;
|
|
345
|
+
try {
|
|
346
|
+
return f(a, state.b, ...args);
|
|
347
|
+
} finally {
|
|
348
|
+
state.a = a;
|
|
349
|
+
real._wbg_cb_unref();
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
real._wbg_cb_unref = () => {
|
|
353
|
+
if (--state.cnt === 0) {
|
|
354
|
+
wasm.__wbindgen_export2(state.a, state.b);
|
|
355
|
+
state.a = 0;
|
|
356
|
+
CLOSURE_DTORS.unregister(state);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
CLOSURE_DTORS.register(real, state, state);
|
|
360
|
+
return real;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function passStringToWasm0(arg, malloc, realloc) {
|
|
364
|
+
if (realloc === undefined) {
|
|
365
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
366
|
+
const ptr = malloc(buf.length, 1) >>> 0;
|
|
367
|
+
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
|
368
|
+
WASM_VECTOR_LEN = buf.length;
|
|
369
|
+
return ptr;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
let len = arg.length;
|
|
373
|
+
let ptr = malloc(len, 1) >>> 0;
|
|
374
|
+
|
|
375
|
+
const mem = getUint8ArrayMemory0();
|
|
376
|
+
|
|
377
|
+
let offset = 0;
|
|
378
|
+
|
|
379
|
+
for (; offset < len; offset++) {
|
|
380
|
+
const code = arg.charCodeAt(offset);
|
|
381
|
+
if (code > 0x7F) break;
|
|
382
|
+
mem[ptr + offset] = code;
|
|
383
|
+
}
|
|
384
|
+
if (offset !== len) {
|
|
385
|
+
if (offset !== 0) {
|
|
386
|
+
arg = arg.slice(offset);
|
|
387
|
+
}
|
|
388
|
+
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
|
389
|
+
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
|
390
|
+
const ret = cachedTextEncoder.encodeInto(arg, view);
|
|
391
|
+
|
|
392
|
+
offset += ret.written;
|
|
393
|
+
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
WASM_VECTOR_LEN = offset;
|
|
397
|
+
return ptr;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function takeObject(idx) {
|
|
401
|
+
const ret = getObject(idx);
|
|
402
|
+
dropObject(idx);
|
|
403
|
+
return ret;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
407
|
+
cachedTextDecoder.decode();
|
|
408
|
+
function decodeText(ptr, len) {
|
|
409
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const cachedTextEncoder = new TextEncoder();
|
|
413
|
+
|
|
414
|
+
if (!('encodeInto' in cachedTextEncoder)) {
|
|
415
|
+
cachedTextEncoder.encodeInto = function (arg, view) {
|
|
416
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
417
|
+
view.set(buf);
|
|
418
|
+
return {
|
|
419
|
+
read: arg.length,
|
|
420
|
+
written: buf.length
|
|
421
|
+
};
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
let WASM_VECTOR_LEN = 0;
|
|
426
|
+
|
|
427
|
+
const wasmPath = `${__dirname}/wl_apdp_wasm_bg.wasm`;
|
|
428
|
+
const wasmBytes = require('fs').readFileSync(wasmPath);
|
|
429
|
+
const wasmModule = new WebAssembly.Module(wasmBytes);
|
|
430
|
+
let wasmInstance = new WebAssembly.Instance(wasmModule, __wbg_get_imports());
|
|
431
|
+
let wasm = wasmInstance.exports;
|
|
Binary file
|