@unyt/datex 0.0.14 → 0.0.15
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/esm/datex-web/datex_web.d.ts +93 -2
- package/esm/datex-web/datex_web.internal.d.ts +215 -197
- package/esm/datex-web/datex_web.internal.d.ts.map +1 -1
- package/esm/datex-web/datex_web.internal.js +437 -407
- package/esm/datex-web/datex_web.wasm +0 -0
- package/esm/datex-web/types/decompiler/options.d.ts +17 -0
- package/esm/datex-web/types/decompiler/options.d.ts.map +1 -0
- package/esm/datex-web/types/decompiler/options.js +4 -0
- package/esm/datex-web/types/disassembler/options.d.ts +6 -0
- package/esm/datex-web/types/disassembler/options.d.ts.map +1 -0
- package/esm/datex-web/types/disassembler/options.js +4 -0
- package/esm/datex-web/types/network/com_hub/managers/socket_manager.d.ts +9 -0
- package/esm/datex-web/types/network/com_hub/managers/socket_manager.d.ts.map +1 -0
- package/esm/datex-web/types/network/com_hub/managers/socket_manager.js +4 -0
- package/esm/datex-web/types/network/com_hub/metadata.d.ts +20 -0
- package/esm/datex-web/types/network/com_hub/metadata.d.ts.map +1 -0
- package/esm/datex-web/types/network/com_hub/metadata.js +4 -0
- package/esm/datex-web/types/network/com_hub/mod.d.ts +6 -0
- package/esm/datex-web/types/network/com_hub/mod.d.ts.map +1 -0
- package/esm/datex-web/types/network/com_hub/mod.js +4 -0
- package/esm/datex-web/types/network/com_hub/network_tracing.d.ts +23 -0
- package/esm/datex-web/types/network/com_hub/network_tracing.d.ts.map +1 -0
- package/esm/datex-web/types/network/com_hub/network_tracing.js +4 -0
- package/esm/datex-web/types/network/com_hub.d.ts +8 -0
- package/esm/datex-web/types/network/com_hub.d.ts.map +1 -0
- package/esm/datex-web/types/network/com_hub.js +4 -0
- package/esm/datex-web/types/network/com_interfaces/com_interface/properties.d.ts +27 -0
- package/esm/datex-web/types/network/com_interfaces/com_interface/properties.d.ts.map +1 -0
- package/esm/datex-web/types/network/com_interfaces/com_interface/properties.js +4 -0
- package/esm/datex-web/types/network/com_interfaces/default_setup_data/http_common.d.ts +10 -0
- package/esm/datex-web/types/network/com_interfaces/default_setup_data/http_common.d.ts.map +1 -0
- package/esm/datex-web/types/network/com_interfaces/default_setup_data/http_common.js +4 -0
- package/esm/datex-web/types/network/com_interfaces/default_setup_data/websocket/websocket_server.d.ts +6 -0
- package/esm/datex-web/types/network/com_interfaces/default_setup_data/websocket/websocket_server.d.ts.map +1 -0
- package/esm/datex-web/types/network/com_interfaces/default_setup_data/websocket/websocket_server.js +4 -0
- package/esm/datex-web/types/runtime/config.d.ts +16 -0
- package/esm/datex-web/types/runtime/config.d.ts.map +1 -0
- package/esm/datex-web/types/runtime/config.js +4 -0
- package/esm/default.d.ts.map +1 -1
- package/esm/default.js +2 -0
- package/esm/deno.json +73 -17
- package/esm/dif/core.d.ts +36 -40
- package/esm/dif/core.d.ts.map +1 -1
- package/esm/dif/core.js +33 -54
- package/esm/dif/dif-handler.d.ts +58 -101
- package/esm/dif/dif-handler.d.ts.map +1 -1
- package/esm/dif/dif-handler.js +411 -365
- package/esm/dif/display.d.ts +14 -5
- package/esm/dif/display.d.ts.map +1 -1
- package/esm/dif/display.js +89 -39
- package/esm/dif/helpers/mod.d.ts +6 -0
- package/esm/dif/helpers/mod.d.ts.map +1 -0
- package/esm/dif/helpers/mod.js +5 -0
- package/esm/dif/helpers/typed-integer.d.ts +14 -0
- package/esm/dif/helpers/typed-integer.d.ts.map +1 -0
- package/esm/dif/helpers/typed-integer.js +37 -0
- package/esm/dif/js-lib.d.ts +14 -1
- package/esm/dif/js-lib.d.ts.map +1 -1
- package/esm/dif/js-lib.js +19 -1
- package/esm/dif/mod.d.ts +2 -2
- package/esm/dif/mod.d.ts.map +1 -1
- package/esm/dif/mod.js +2 -2
- package/esm/dif/type-registry.d.ts +30 -21
- package/esm/dif/type-registry.d.ts.map +1 -1
- package/esm/dif/type-registry.js +45 -33
- package/esm/dif/types/mod.d.ts +9 -0
- package/esm/dif/types/mod.d.ts.map +1 -0
- package/esm/dif/types/mod.js +8 -0
- package/esm/dif/types/type.d.ts +91 -0
- package/esm/dif/types/type.d.ts.map +1 -0
- package/esm/dif/types/type.js +33 -0
- package/esm/dif/types/update.d.ts +63 -0
- package/esm/dif/types/update.d.ts.map +1 -0
- package/esm/dif/types/update.js +16 -0
- package/esm/dif/types/value.d.ts +62 -0
- package/esm/dif/types/value.d.ts.map +1 -0
- package/esm/dif/types/value.js +1 -0
- package/esm/dif/update.d.ts +20 -0
- package/esm/dif/update.d.ts.map +1 -0
- package/esm/dif/update.js +41 -0
- package/esm/dif/utils.d.ts +8 -0
- package/esm/dif/utils.d.ts.map +1 -0
- package/esm/dif/utils.js +67 -0
- package/esm/lib/js-core-types/array.d.ts +3 -0
- package/esm/lib/js-core-types/array.d.ts.map +1 -0
- package/esm/lib/js-core-types/array.js +175 -0
- package/esm/lib/js-core-types/map.d.ts +15 -0
- package/esm/lib/js-core-types/map.d.ts.map +1 -0
- package/esm/lib/js-core-types/map.js +88 -0
- package/esm/lib/js-core-types/mod.d.ts +8 -0
- package/esm/lib/js-core-types/mod.d.ts.map +1 -0
- package/esm/lib/js-core-types/mod.js +7 -0
- package/esm/lib/mod.d.ts +8 -0
- package/esm/lib/mod.d.ts.map +1 -0
- package/esm/lib/mod.js +7 -0
- package/esm/lib/special-core-types/mod.d.ts +9 -0
- package/esm/lib/special-core-types/mod.d.ts.map +1 -0
- package/esm/lib/special-core-types/mod.js +8 -0
- package/esm/lib/special-core-types/tagged.d.ts +17 -0
- package/esm/lib/special-core-types/tagged.d.ts.map +1 -0
- package/esm/lib/special-core-types/tagged.js +37 -0
- package/esm/lib/special-core-types/undefined.d.ts +7 -0
- package/esm/lib/special-core-types/undefined.d.ts.map +1 -0
- package/esm/lib/special-core-types/undefined.js +28 -0
- package/esm/mod.d.ts +2 -3
- package/esm/mod.d.ts.map +1 -1
- package/esm/mod.js +2 -3
- package/esm/network/com-hub.d.ts +28 -1
- package/esm/network/com-hub.d.ts.map +1 -1
- package/esm/network/com-hub.js +6 -2
- package/esm/network/interfaces/websocket-server-base.d.ts +1 -1
- package/esm/network/interfaces/websocket-server-base.d.ts.map +1 -1
- package/esm/network/interfaces/websocket-server-base.js +8 -7
- package/esm/network/interfaces/websocket-server-deno.d.ts +1 -1
- package/esm/network/interfaces/websocket-server-deno.d.ts.map +1 -1
- package/esm/repl/mod.js +1 -1
- package/esm/runtime/runtime.d.ts +43 -18
- package/esm/runtime/runtime.d.ts.map +1 -1
- package/esm/runtime/runtime.js +55 -32
- package/esm/{refs/ref.d.ts → shared-container/base-shared-container.d.ts} +13 -5
- package/esm/shared-container/base-shared-container.d.ts.map +1 -0
- package/esm/shared-container/base-shared-container.js +95 -0
- package/esm/shared-container/mod.d.ts +36 -0
- package/esm/shared-container/mod.d.ts.map +1 -0
- package/esm/shared-container/mod.js +29 -0
- package/esm/shared-container/owned.d.ts +33 -0
- package/esm/shared-container/owned.d.ts.map +1 -0
- package/esm/shared-container/owned.js +60 -0
- package/esm/shared-container/reference.d.ts +31 -0
- package/esm/shared-container/reference.d.ts.map +1 -0
- package/esm/shared-container/reference.js +64 -0
- package/esm/utils/devtools-formatter.js +2 -2
- package/esm/utils/option.d.ts +17 -0
- package/esm/utils/option.d.ts.map +1 -0
- package/esm/utils/option.js +54 -0
- package/package.json +1 -1
- package/esm/dif/definitions.d.ts +0 -134
- package/esm/dif/definitions.d.ts.map +0 -1
- package/esm/dif/definitions.js +0 -38
- package/esm/refs/ref.d.ts.map +0 -1
- package/esm/refs/ref.js +0 -60
package/esm/dif/dif-handler.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module DIF Handler
|
|
3
|
+
* Represents the main interface for interacting with the DATEX Core via DIF from JavaScript.
|
|
4
|
+
*/
|
|
1
5
|
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
6
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
7
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
@@ -10,14 +14,68 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
10
14
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
15
|
};
|
|
12
16
|
var _DIFHandler_runtime, _DIFHandler_handle, _DIFHandler_transceiver_id, _DIFHandler_cache, _DIFHandler_proxyMapping, _DIFHandler_referenceMetadata, _DIFHandler_observers, _DIFHandler_type_registry;
|
|
13
|
-
import { Ref } from "../refs/ref.js";
|
|
14
17
|
import { Endpoint } from "../lib/special-core-types/endpoint.js";
|
|
15
18
|
import { Range } from "../lib/special-core-types/range.js";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
19
|
+
import { DIFUpdateKind, } from "./types/mod.js";
|
|
20
|
+
import { CoreLibTypeId } from "./core.js";
|
|
18
21
|
import { TypeRegistry } from "./type-registry.js";
|
|
19
|
-
import { panic } from "../utils/exceptions.js";
|
|
22
|
+
import { panic, unimplemented, unreachable } from "../utils/exceptions.js";
|
|
23
|
+
import { isJsUndefined, JS_UNDEFINED } from "../lib/special-core-types/undefined.js";
|
|
24
|
+
import { SharedContainerMutability } from "../shared-container/base-shared-container.js";
|
|
25
|
+
import { BaseSharedContainer } from "../shared-container/mod.js";
|
|
26
|
+
import { DIFSharedContainerOwnership } from "./types/type.js";
|
|
27
|
+
import { splitPointerAddressWithOwnership } from "../shared-container/mod.js";
|
|
28
|
+
import { combinePointerAddressWithOwnership } from "../shared-container/mod.js";
|
|
29
|
+
import { appendEntry, clear, deleteEntry, DIFPropertyKind, listSplice, replace, setEntry } from "./update.js";
|
|
30
|
+
import { createDIFProperty } from "./update.js";
|
|
20
31
|
import { JsLibTypeAddress } from "./js-lib.js";
|
|
32
|
+
import { isJsMapTypeDefinition } from "../lib/mod.js";
|
|
33
|
+
import { OwnedSharedContainer } from "../shared-container/owned.js";
|
|
34
|
+
import { EMPTY_TAG, Tagged } from "../lib/special-core-types/tagged.js";
|
|
35
|
+
import { ibig } from "./helpers/mod.js";
|
|
36
|
+
/**
|
|
37
|
+
* Some DIF methods may return an optional ValueContainer, so does the execute_sync, when no result is returned.
|
|
38
|
+
* DIF must differentiate between null and no result, so we wrap DIFOptionalValueContainer.
|
|
39
|
+
* @param value - The DIFOptionalValueContainer to collapse.
|
|
40
|
+
* @returns The contained DIFValueContainer if present, or undefined if the value is not present.
|
|
41
|
+
*/
|
|
42
|
+
function collapseDIFOption(value) {
|
|
43
|
+
if (value === null) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
if (Array.isArray(value) && value.length === 1) {
|
|
48
|
+
return value[0];
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
throw new Error("Invalid DIFOptionalValueContainer format: expected an array of length 1 or null");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Converts special float string representations ("nan", "infinity", "-infinity") to the JS values NaN, Infinity and -Infinity respectively.
|
|
57
|
+
* @param value - The string representation of the float value.
|
|
58
|
+
* @returns The corresponding JS number value for the special float representation.
|
|
59
|
+
* @throws If the input value is not a valid special float representation.
|
|
60
|
+
*/
|
|
61
|
+
function specialDIFFloatToNumber(value) {
|
|
62
|
+
if (!isSpecialDIFFloatString(value)) {
|
|
63
|
+
throw new Error(`Expected a special float string ("nan", "infinity", "-infinity"), got ${value}`);
|
|
64
|
+
}
|
|
65
|
+
if (value === "nan") {
|
|
66
|
+
return NaN;
|
|
67
|
+
}
|
|
68
|
+
else if (value === "infinity") {
|
|
69
|
+
return Infinity;
|
|
70
|
+
}
|
|
71
|
+
else if (value === "-infinity") {
|
|
72
|
+
return -Infinity;
|
|
73
|
+
}
|
|
74
|
+
unreachable(`Invalid special float string: ${value}`);
|
|
75
|
+
}
|
|
76
|
+
function isSpecialDIFFloatString(value) {
|
|
77
|
+
return ["nan", "infinity", "-infinity"].includes(value);
|
|
78
|
+
}
|
|
21
79
|
export const IS_PROXY_ACCESS = Symbol("IS_PROXY_ACCESS");
|
|
22
80
|
/**
|
|
23
81
|
* The DIFHandler class provides methods to interact with the DATEX Core DIF runtime,
|
|
@@ -34,7 +92,7 @@ export class DIFHandler {
|
|
|
34
92
|
}
|
|
35
93
|
/**
|
|
36
94
|
* Internal property
|
|
37
|
-
* @returns The
|
|
95
|
+
* @returns The {@link JSDIFInterface} instance.
|
|
38
96
|
*/
|
|
39
97
|
get _handle() {
|
|
40
98
|
return __classPrivateFieldGet(this, _DIFHandler_handle, "f");
|
|
@@ -52,7 +110,6 @@ export class DIFHandler {
|
|
|
52
110
|
/**
|
|
53
111
|
* Creates a new DIFHandler instance.
|
|
54
112
|
* @param runtime - The JSRuntime instance for executing Datex scripts.
|
|
55
|
-
* @param pointerCache - The PointerCache instance for managing object pointers. If not provided, a new PointerCache will be created.
|
|
56
113
|
*/
|
|
57
114
|
constructor(runtime) {
|
|
58
115
|
/** The JSRuntime interface for the underlying Datex Core runtime */
|
|
@@ -77,7 +134,7 @@ export class DIFHandler {
|
|
|
77
134
|
_DIFHandler_observers.set(this, new Map());
|
|
78
135
|
_DIFHandler_type_registry.set(this, new TypeRegistry(this));
|
|
79
136
|
__classPrivateFieldSet(this, _DIFHandler_runtime, runtime, "f");
|
|
80
|
-
__classPrivateFieldSet(this, _DIFHandler_handle, runtime.
|
|
137
|
+
__classPrivateFieldSet(this, _DIFHandler_handle, runtime.dif_interface(), "f");
|
|
81
138
|
}
|
|
82
139
|
/**
|
|
83
140
|
* Executes a Datex script asynchronously and returns a Promise that resolves to a DIFContainer.
|
|
@@ -86,8 +143,8 @@ export class DIFHandler {
|
|
|
86
143
|
* @returns A Promise that resolves to the execution result as a DIFContainer.
|
|
87
144
|
* @throws If an error occurs during execution.
|
|
88
145
|
*/
|
|
89
|
-
executeDIF(datexScript, values = []) {
|
|
90
|
-
return __classPrivateFieldGet(this, _DIFHandler_runtime, "f").execute(datexScript, this.convertToDIFValues(values));
|
|
146
|
+
async executeDIF(datexScript, values = []) {
|
|
147
|
+
return collapseDIFOption(await __classPrivateFieldGet(this, _DIFHandler_runtime, "f").execute(datexScript, this.convertToDIFValues(values)));
|
|
91
148
|
}
|
|
92
149
|
/**
|
|
93
150
|
* Executes a Datex script synchronously and returns the result as a DIFContainer.
|
|
@@ -97,7 +154,7 @@ export class DIFHandler {
|
|
|
97
154
|
* @throws If an error occurs during execution.
|
|
98
155
|
*/
|
|
99
156
|
executeSyncDIF(datexScript, values = []) {
|
|
100
|
-
return __classPrivateFieldGet(this, _DIFHandler_runtime, "f").execute_sync(datexScript, this.convertToDIFValues(values));
|
|
157
|
+
return collapseDIFOption(__classPrivateFieldGet(this, _DIFHandler_runtime, "f").execute_sync(datexScript, this.convertToDIFValues(values)));
|
|
101
158
|
}
|
|
102
159
|
/**
|
|
103
160
|
* Creates a new shared value for the specified DIF value.
|
|
@@ -106,16 +163,23 @@ export class DIFHandler {
|
|
|
106
163
|
* @param mutability - The mutability of the pointer.
|
|
107
164
|
* @returns The created pointer address.
|
|
108
165
|
*/
|
|
109
|
-
|
|
110
|
-
|
|
166
|
+
constructSharedValue(difValueContainer, mutability = SharedContainerMutability.Mutable, allowedType = null) {
|
|
167
|
+
const baseSharedValueContainer = [
|
|
168
|
+
difValueContainer,
|
|
169
|
+
mutability,
|
|
170
|
+
];
|
|
171
|
+
if (allowedType) {
|
|
172
|
+
baseSharedValueContainer[2] = allowedType;
|
|
173
|
+
}
|
|
174
|
+
return __classPrivateFieldGet(this, _DIFHandler_handle, "f").create_pointer(baseSharedValueContainer);
|
|
111
175
|
}
|
|
112
176
|
/**
|
|
113
177
|
* Updates the DIF value at the specified address.
|
|
114
178
|
* @param address - The address of the DIF value to update.
|
|
115
|
-
* @param
|
|
179
|
+
* @param update_data - The DIFUpdate object containing the update information.
|
|
116
180
|
*/
|
|
117
|
-
|
|
118
|
-
__classPrivateFieldGet(this, _DIFHandler_handle, "f").update(__classPrivateFieldGet(this, _DIFHandler_transceiver_id, "f"),
|
|
181
|
+
updateSharedValue(address, update_data) {
|
|
182
|
+
return __classPrivateFieldGet(this, _DIFHandler_handle, "f").update(address, [__classPrivateFieldGet(this, _DIFHandler_transceiver_id, "f"), ...update_data]);
|
|
119
183
|
}
|
|
120
184
|
/**
|
|
121
185
|
* Registers an observer callback for changes to the DIF value at the specified address
|
|
@@ -128,8 +192,8 @@ export class DIFHandler {
|
|
|
128
192
|
* @returns An observer ID that can be used to unregister the observer.
|
|
129
193
|
* @throws If the pointer is final.
|
|
130
194
|
*/
|
|
131
|
-
|
|
132
|
-
return __classPrivateFieldGet(this, _DIFHandler_runtime, "f").
|
|
195
|
+
observeSharedValueBindDirect(address, callback, options = { relay_own_updates: false }) {
|
|
196
|
+
return __classPrivateFieldGet(this, _DIFHandler_runtime, "f").dif_interface().observe_pointer(__classPrivateFieldGet(this, _DIFHandler_transceiver_id, "f"), address, options, callback);
|
|
133
197
|
}
|
|
134
198
|
/**
|
|
135
199
|
* Updates the observe options for a registered observer.
|
|
@@ -138,7 +202,7 @@ export class DIFHandler {
|
|
|
138
202
|
* @param options - The new observe options to apply.
|
|
139
203
|
*/
|
|
140
204
|
updateObserverOptions(address, observerId, options) {
|
|
141
|
-
__classPrivateFieldGet(this, _DIFHandler_runtime, "f").
|
|
205
|
+
__classPrivateFieldGet(this, _DIFHandler_runtime, "f").dif_interface().update_observer_options(address, observerId, options);
|
|
142
206
|
}
|
|
143
207
|
/**
|
|
144
208
|
* Enables propagation of own updates for a registered observer.
|
|
@@ -167,8 +231,8 @@ export class DIFHandler {
|
|
|
167
231
|
* @param address - The address of the DIF value being observed.
|
|
168
232
|
* @param observerId - The observer ID returned by the observePointer method.
|
|
169
233
|
*/
|
|
170
|
-
|
|
171
|
-
__classPrivateFieldGet(this, _DIFHandler_runtime, "f").
|
|
234
|
+
unobserveSharedValueBindDirect(address, observerId) {
|
|
235
|
+
__classPrivateFieldGet(this, _DIFHandler_runtime, "f").dif_interface().unobserve_pointer(address, observerId);
|
|
172
236
|
}
|
|
173
237
|
/**
|
|
174
238
|
* Registers a local observer callback for changes to the DIF value at the specified address.
|
|
@@ -185,7 +249,7 @@ export class DIFHandler {
|
|
|
185
249
|
let cached = __classPrivateFieldGet(this, _DIFHandler_cache, "f").get(address);
|
|
186
250
|
if (!cached) {
|
|
187
251
|
// first resolve the pointer to make sure it's loaded in the cache
|
|
188
|
-
this.
|
|
252
|
+
this.resolvePointerAddress(DIFSharedContainerOwnership.Immutable, address);
|
|
189
253
|
cached = __classPrivateFieldGet(this, _DIFHandler_cache, "f").get(address);
|
|
190
254
|
}
|
|
191
255
|
// make sure the pointer is not final (no observer)
|
|
@@ -236,147 +300,176 @@ export class DIFHandler {
|
|
|
236
300
|
* @param value
|
|
237
301
|
*/
|
|
238
302
|
resolveDIFValue(value) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
303
|
+
// direct interpretation of trivial types without type annotation
|
|
304
|
+
if (value === null) {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
else if (isJsUndefined(value)) {
|
|
308
|
+
return undefined;
|
|
309
|
+
}
|
|
310
|
+
else if (typeof value === "string") {
|
|
311
|
+
return value;
|
|
312
|
+
}
|
|
313
|
+
else if (typeof value === "boolean") {
|
|
314
|
+
return value;
|
|
315
|
+
}
|
|
316
|
+
else if (typeof value === "number") {
|
|
317
|
+
return value;
|
|
318
|
+
}
|
|
319
|
+
// custom interpretation means
|
|
320
|
+
if (!Array.isArray(value) || value.length < 2 || value.length > 3) {
|
|
321
|
+
console.log("value", value);
|
|
322
|
+
throw new Error("Invalid DIFValue format: expected an array for non-primitive types");
|
|
323
|
+
}
|
|
324
|
+
const [type, core, definition] = value;
|
|
325
|
+
let val = null;
|
|
326
|
+
if (type === CoreLibTypeId.null) {
|
|
327
|
+
if (core !== null) {
|
|
328
|
+
throw new Error("Expected null value for null type");
|
|
251
329
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
return value.value;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
// null, boolean and text types values are just returned as is
|
|
261
|
-
if (type === CoreTypeAddress.boolean ||
|
|
262
|
-
type == CoreTypeAddress.text ||
|
|
263
|
-
type === CoreTypeAddress.null) {
|
|
264
|
-
return value.value;
|
|
265
|
-
} // small integers are interpreted as JS numbers
|
|
266
|
-
else if (typeof type === "string" && (type == CoreTypeAddress.integer ||
|
|
267
|
-
this.isPointerAddressInAdresses(type, CoreTypeAddressRanges.small_signed_integers) ||
|
|
268
|
-
this.isPointerAddressInAdresses(type, CoreTypeAddressRanges.small_unsigned_integers))) {
|
|
269
|
-
return Number(value.value);
|
|
270
|
-
} // big integers are interpreted as JS BigInt
|
|
271
|
-
else if (typeof type === "string" && (this.isPointerAddressInAdresses(type, CoreTypeAddressRanges.big_signed_integers))) {
|
|
272
|
-
return BigInt(value.value);
|
|
273
|
-
} // decimal types are interpreted as JS numbers
|
|
274
|
-
else if (typeof type === "string" &&
|
|
275
|
-
this.isPointerAddressInAdresses(type, CoreTypeAddressRanges.decimals)) {
|
|
276
|
-
return Number(value.value);
|
|
277
|
-
} // endpoint types are resolved to Endpoint instances
|
|
278
|
-
else if (type === CoreTypeAddress.endpoint) {
|
|
279
|
-
return Endpoint.get(value.value);
|
|
280
|
-
}
|
|
281
|
-
else if (type === CoreTypeAddress.range) {
|
|
282
|
-
const [start, end] = value.value;
|
|
283
|
-
const result = this.promiseAllOrSync([
|
|
284
|
-
this.resolveDIFValueContainer(start),
|
|
285
|
-
this.resolveDIFValueContainer(end),
|
|
286
|
-
]);
|
|
287
|
-
if (result instanceof Promise) {
|
|
288
|
-
return result.then(([start, end]) => {
|
|
289
|
-
return new Range(start, end);
|
|
290
|
-
});
|
|
330
|
+
val = null;
|
|
331
|
+
}
|
|
332
|
+
else if (type === CoreLibTypeId.boolean) {
|
|
333
|
+
if (typeof core !== "boolean") {
|
|
334
|
+
throw new Error("Expected boolean value for boolean type");
|
|
291
335
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
336
|
+
val = core;
|
|
337
|
+
}
|
|
338
|
+
else if ([
|
|
339
|
+
CoreLibTypeId.integer_i8,
|
|
340
|
+
CoreLibTypeId.integer_i16,
|
|
341
|
+
CoreLibTypeId.integer_i32,
|
|
342
|
+
CoreLibTypeId.integer_u8,
|
|
343
|
+
CoreLibTypeId.integer_u16,
|
|
344
|
+
CoreLibTypeId.integer_u32,
|
|
345
|
+
CoreLibTypeId.integer_i64,
|
|
346
|
+
].includes(type)) {
|
|
347
|
+
if (typeof core !== "number") {
|
|
348
|
+
throw new Error("Expected number value for integer type");
|
|
349
|
+
}
|
|
350
|
+
val = core;
|
|
351
|
+
}
|
|
352
|
+
else if (type === CoreLibTypeId.integer) {
|
|
353
|
+
if (typeof core === "string") {
|
|
354
|
+
val = parseInt(core, 10);
|
|
355
|
+
}
|
|
356
|
+
else
|
|
357
|
+
throw new Error("Expected number value for integer type");
|
|
358
|
+
}
|
|
359
|
+
else if ([
|
|
360
|
+
CoreLibTypeId.integer_i128,
|
|
361
|
+
CoreLibTypeId.integer_u64,
|
|
362
|
+
CoreLibTypeId.integer_u128,
|
|
363
|
+
CoreLibTypeId.integer_ibig,
|
|
364
|
+
].includes(type)) {
|
|
365
|
+
if (typeof core !== "string" && typeof core !== "number") {
|
|
366
|
+
throw new Error("Expected string or number value for big integer type");
|
|
367
|
+
}
|
|
368
|
+
val = BigInt(core);
|
|
369
|
+
}
|
|
370
|
+
else if ([
|
|
371
|
+
CoreLibTypeId.decimal_dbig,
|
|
372
|
+
CoreLibTypeId.decimal, // FIXME rational notation 3/4
|
|
373
|
+
].includes(type)) {
|
|
374
|
+
if (typeof core !== "string") {
|
|
375
|
+
throw new Error("Expected string value for decimal big type" + typeof core + " " + JSON.stringify(core));
|
|
376
|
+
}
|
|
377
|
+
if (isSpecialDIFFloatString(core)) {
|
|
378
|
+
val = specialDIFFloatToNumber(core);
|
|
379
|
+
} // FIXME this is a temporary solution until we have a proper decimal implementation
|
|
380
|
+
else if (core.includes("/")) {
|
|
381
|
+
const [numerator, denominator] = core.split("/").map((part) => part.trim());
|
|
382
|
+
val = parseFloat(numerator) / parseFloat(denominator);
|
|
383
|
+
}
|
|
384
|
+
else if (core.includes(".")) {
|
|
385
|
+
val = parseFloat(core);
|
|
308
386
|
}
|
|
309
387
|
else {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
for (const [key, val] of Object.entries(value.value)) {
|
|
320
|
-
resolvedMap.set(key, this.resolveDIFValueContainer(val));
|
|
321
|
-
}
|
|
322
|
-
return resolvedMap;
|
|
323
|
-
}
|
|
388
|
+
throw new Error("Expected a valid decimal string for decimal big type");
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
else if ([
|
|
392
|
+
CoreLibTypeId.decimal_f32,
|
|
393
|
+
CoreLibTypeId.decimal_f64,
|
|
394
|
+
].includes(type)) {
|
|
395
|
+
if (typeof core === "string") {
|
|
396
|
+
val = specialDIFFloatToNumber(core);
|
|
324
397
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
type.def[1].length === 1 &&
|
|
331
|
-
type.def[1][0] == JsLibTypeAddress.undefined) {
|
|
332
|
-
return undefined;
|
|
398
|
+
else if (typeof core === "number") {
|
|
399
|
+
val = core;
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
throw new Error("Expected number value for decimal type");
|
|
333
403
|
}
|
|
334
404
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
* or an array of resolved values if all values are already resolved.
|
|
341
|
-
*/
|
|
342
|
-
promiseAllOrSync(values) {
|
|
343
|
-
if (values.some((v) => v instanceof Promise)) {
|
|
344
|
-
return Promise.all(values);
|
|
405
|
+
else if (type === CoreLibTypeId.text) {
|
|
406
|
+
if (typeof core !== "string") {
|
|
407
|
+
throw new Error("Expected string value for text type");
|
|
408
|
+
}
|
|
409
|
+
val = core;
|
|
345
410
|
}
|
|
346
|
-
else {
|
|
347
|
-
|
|
411
|
+
else if (type === CoreLibTypeId.endpoint) {
|
|
412
|
+
if (typeof core !== "string") {
|
|
413
|
+
throw new Error("Expected string value for endpoint type");
|
|
414
|
+
}
|
|
415
|
+
val = Endpoint.get(core);
|
|
348
416
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
for (const key of Object.keys(values)) {
|
|
361
|
-
resolvedObj[key] = resolvedValues[i++];
|
|
362
|
-
}
|
|
363
|
-
return resolvedObj;
|
|
364
|
-
});
|
|
417
|
+
else if (type === CoreLibTypeId.Range) {
|
|
418
|
+
if (!Array.isArray(core) || core.length !== 2) {
|
|
419
|
+
throw new Error("Expected array of length 2 for range type");
|
|
420
|
+
}
|
|
421
|
+
const [start, end] = core;
|
|
422
|
+
const res = [
|
|
423
|
+
this.resolveDIFValueContainer(start),
|
|
424
|
+
this.resolveDIFValueContainer(end),
|
|
425
|
+
];
|
|
426
|
+
// FIXME fix range
|
|
427
|
+
val = new Range(res[0], res[1]);
|
|
365
428
|
}
|
|
366
|
-
else {
|
|
367
|
-
|
|
429
|
+
else if (type === CoreLibTypeId.List) {
|
|
430
|
+
if (!Array.isArray(core)) {
|
|
431
|
+
throw new Error("Expected array value for list type");
|
|
432
|
+
}
|
|
433
|
+
val = core.map((v) => this.resolveDIFValueContainer(v));
|
|
368
434
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
435
|
+
else if (type === CoreLibTypeId.Map) {
|
|
436
|
+
if (Array.isArray(core)) {
|
|
437
|
+
const map = new Map();
|
|
438
|
+
for (const [key, value] of core) {
|
|
439
|
+
map.set(this.resolveDIFValueContainer(key), this.resolveDIFValueContainer(value));
|
|
440
|
+
}
|
|
441
|
+
val = map;
|
|
442
|
+
}
|
|
443
|
+
else if (typeof core === "object" && core !== null) {
|
|
444
|
+
const obj = {};
|
|
445
|
+
for (const [key, value] of Object.entries(core)) {
|
|
446
|
+
obj[key] = this.resolveDIFValueContainer(value);
|
|
447
|
+
}
|
|
448
|
+
val = obj;
|
|
449
|
+
if (definition && isJsMapTypeDefinition(definition)) {
|
|
450
|
+
val = new Map(Object.entries(obj));
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
throw new Error("Expected array of key-value pairs or object for map type");
|
|
455
|
+
}
|
|
376
456
|
}
|
|
377
|
-
|
|
378
|
-
|
|
457
|
+
// for tagged type definition, wrap in Tagged
|
|
458
|
+
if (definition && typeof definition === "object" && "tagged_type" in definition) {
|
|
459
|
+
const [tag, innerType] = definition.tagged_type;
|
|
460
|
+
// special case: empty tag
|
|
461
|
+
if (val === null && innerType === CoreLibTypeId.Unit) {
|
|
462
|
+
val = new Tagged(tag, EMPTY_TAG);
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
// TODO: handle other innerTypes if not default type
|
|
466
|
+
val = new Tagged(tag, val);
|
|
467
|
+
}
|
|
379
468
|
}
|
|
469
|
+
// FIXME custom type resolution not implemented yet, just return the core value for now
|
|
470
|
+
return val;
|
|
471
|
+
// custom types not implemented yet
|
|
472
|
+
// throw new Error("Custom type resolution not implemented yet");
|
|
380
473
|
}
|
|
381
474
|
/**
|
|
382
475
|
* Resolves a DIFValueContainer (either a DIFValue or a pointer address) to its corresponding JS value.
|
|
@@ -386,41 +479,27 @@ export class DIFHandler {
|
|
|
386
479
|
* @returns The resolved value as type T, or a Promise that resolves to type T.
|
|
387
480
|
*/
|
|
388
481
|
resolveDIFValueContainer(value) {
|
|
389
|
-
if (typeof value !== "
|
|
390
|
-
return this.
|
|
482
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value) && "$" in value) {
|
|
483
|
+
return this.resolvePointerAddress(...splitPointerAddressWithOwnership(value.$));
|
|
391
484
|
}
|
|
392
485
|
else {
|
|
393
|
-
return this.
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Synchronous version of resolveDIFValueContainer.
|
|
398
|
-
* This method can only be used if the value only contains pointer addresses that are already loaded in memory -
|
|
399
|
-
* otherwise, use the asynchronous `resolveDIFValueContainer` method instead.
|
|
400
|
-
* @param value - The DIFValueContainer to resolve.
|
|
401
|
-
* @returns The resolved value as type T.
|
|
402
|
-
* @throws If the resolution would require asynchronous operations.
|
|
403
|
-
*/
|
|
404
|
-
resolveDIFValueContainerSync(value) {
|
|
405
|
-
const result = this.resolveDIFValueContainer(value);
|
|
406
|
-
if (result instanceof Promise) {
|
|
407
|
-
throw new Error("resolveDIFValueContainerSync cannot return a Promise. Use resolveDIFValueContainer() instead.");
|
|
486
|
+
return this.resolveDIFValue(value);
|
|
408
487
|
}
|
|
409
|
-
return result;
|
|
410
488
|
}
|
|
411
489
|
/**
|
|
412
490
|
* Resolves a DIFProperty to its corresponding JS value.
|
|
413
491
|
*/
|
|
414
|
-
|
|
415
|
-
if (property
|
|
416
|
-
return property
|
|
492
|
+
resolveDIFProperty(property) {
|
|
493
|
+
if (typeof property === "number") {
|
|
494
|
+
return property;
|
|
417
495
|
}
|
|
418
|
-
|
|
419
|
-
return property
|
|
496
|
+
if (typeof property === "string") {
|
|
497
|
+
return property;
|
|
420
498
|
}
|
|
421
|
-
|
|
422
|
-
return this.
|
|
499
|
+
if (typeof property === "object" && property !== null && !Array.isArray(property) && "value" in property) {
|
|
500
|
+
return this.resolveDIFValueContainer(property.value);
|
|
423
501
|
}
|
|
502
|
+
throw new Error("Invalid DIFProperty format");
|
|
424
503
|
}
|
|
425
504
|
/**
|
|
426
505
|
* Resolves a pointer address to its corresponding JS value.
|
|
@@ -429,43 +508,33 @@ export class DIFHandler {
|
|
|
429
508
|
* @param address - The pointer address to resolve.
|
|
430
509
|
* @returns The resolved value as type T, or a Promise that resolves to type T.
|
|
431
510
|
*/
|
|
432
|
-
resolvePointerAddress(address) {
|
|
511
|
+
resolvePointerAddress(ownership, address) {
|
|
512
|
+
const addressWithOwnership = combinePointerAddressWithOwnership(address, ownership);
|
|
433
513
|
// check cache first
|
|
434
|
-
const cached = this.
|
|
435
|
-
if (cached) {
|
|
436
|
-
|
|
514
|
+
const cached = this.getCachedStateForSharedContainer(address, ownership);
|
|
515
|
+
if (cached === "insufficient_ownership") {
|
|
516
|
+
// try to resolve with with upgraded owership if possible
|
|
517
|
+
if (!__classPrivateFieldGet(this, _DIFHandler_handle, "f").has_address_with_ownership(addressWithOwnership)) {
|
|
518
|
+
throw new Error(`Address ${address} not found in runtime with ownership ${ownership} or higher`);
|
|
519
|
+
}
|
|
520
|
+
__classPrivateFieldGet(this, _DIFHandler_cache, "f").get(address).maxOwnership = ownership;
|
|
521
|
+
const upgraded = this.getCachedStateForSharedContainer(address, ownership);
|
|
522
|
+
if (typeof upgraded === "string") {
|
|
523
|
+
unreachable(`Ownership assertion passed but cache still returns ${upgraded}`);
|
|
524
|
+
}
|
|
525
|
+
return upgraded;
|
|
437
526
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
const value = this.resolveDIFValueContainer(
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
/**
|
|
450
|
-
* Resolves a pointer address to its corresponding JS value synchronously.
|
|
451
|
-
* If the pointer address is not yet loaded in memory, it returns a Promise that resolves to the value.
|
|
452
|
-
* Otherwise, it returns the resolved value directly.
|
|
453
|
-
* @param address - The pointer address to resolve.
|
|
454
|
-
* @returns The resolved value as type T, or a Promise that resolves to type T.
|
|
455
|
-
* @throws If the resolution would require asynchronous operations.
|
|
456
|
-
*/
|
|
457
|
-
resolvePointerAddressSync(address) {
|
|
458
|
-
// check cache first
|
|
459
|
-
const cached = this.getCachedReference(address);
|
|
460
|
-
if (cached) {
|
|
527
|
+
else if (cached === "not_cached") {
|
|
528
|
+
// if not in cache, resolve from runtime
|
|
529
|
+
const base = __classPrivateFieldGet(this, _DIFHandler_handle, "f").resolve_pointer_address(addressWithOwnership);
|
|
530
|
+
const value = this.resolveDIFValueContainer(base[0]);
|
|
531
|
+
// init pointer
|
|
532
|
+
return this.initSharedValue(address, value, base[1], ownership, base[2]);
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
// falltrough case, already in cache with correct ownership
|
|
461
536
|
return cached;
|
|
462
537
|
}
|
|
463
|
-
// if not in cache, resolve from runtime
|
|
464
|
-
const entry = __classPrivateFieldGet(this, _DIFHandler_handle, "f")
|
|
465
|
-
.resolve_pointer_address_sync(address);
|
|
466
|
-
const value = this.resolveDIFValueContainerSync(entry.value);
|
|
467
|
-
this.initReference(address, value, entry.mut, entry.allowed_type);
|
|
468
|
-
return value;
|
|
469
538
|
}
|
|
470
539
|
/**
|
|
471
540
|
* Retrieves the original value from a proxy value if available
|
|
@@ -506,25 +575,28 @@ export class DIFHandler {
|
|
|
506
575
|
return values?.map((value) => this.convertJSValueToDIFValueContainer(value)) ||
|
|
507
576
|
null;
|
|
508
577
|
}
|
|
509
|
-
/**
|
|
510
|
-
* Returns true if the given address is within the specified address range.
|
|
511
|
-
*/
|
|
512
|
-
isPointerAddressInAdresses(address, range) {
|
|
513
|
-
return range.has(address);
|
|
514
|
-
}
|
|
515
578
|
/**
|
|
516
579
|
* Initializes a reference with the given value and mutability, by
|
|
517
580
|
* adding a proxy wrapper if necessary, and setting up observation and caching on the JS side.
|
|
518
581
|
*/
|
|
519
|
-
|
|
520
|
-
let wrappedValue = this.wrapJSValue(value, pointerAddress, allowedType);
|
|
582
|
+
initSharedValue(pointerAddress, value, mutability, ownership, allowedType) {
|
|
583
|
+
let wrappedValue = this.wrapJSValue(value, pointerAddress, mutability, allowedType);
|
|
521
584
|
let typeBinding = null;
|
|
522
585
|
let metadata = undefined;
|
|
523
586
|
// bind js value (if mutable, nominal type)
|
|
524
|
-
const
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
587
|
+
const implType = typeof allowedType === "object" && allowedType !== null && "impl_type" in allowedType
|
|
588
|
+
? allowedType.impl_type
|
|
589
|
+
: null;
|
|
590
|
+
if (implType && implType[0] === CoreLibTypeId.Map) {
|
|
591
|
+
// FIXME can we make this cleaner, or do we need it more generic?
|
|
592
|
+
allowedType = implType[0];
|
|
593
|
+
}
|
|
594
|
+
const bindJSValue = mutability !== SharedContainerMutability.Immutable &&
|
|
595
|
+
(typeof allowedType === "string" || typeof allowedType === "number");
|
|
596
|
+
if (bindJSValue && !(wrappedValue instanceof BaseSharedContainer)) {
|
|
597
|
+
typeBinding = typeof allowedType == "number"
|
|
598
|
+
? this.type_registry.getTypeBindingByCoreLibTypeId(allowedType)
|
|
599
|
+
: this.type_registry.getTypeBinding(allowedType); // TS Bug
|
|
528
600
|
if (typeBinding) {
|
|
529
601
|
const { value, metadata: newMetadata } = typeBinding
|
|
530
602
|
.bindValue(wrappedValue, pointerAddress);
|
|
@@ -534,12 +606,13 @@ export class DIFHandler {
|
|
|
534
606
|
}
|
|
535
607
|
// if not immutable, observe to keep the pointer 'live' and receive updates
|
|
536
608
|
let observerId = null;
|
|
537
|
-
if (mutability !==
|
|
538
|
-
observerId = this.
|
|
609
|
+
if (mutability !== SharedContainerMutability.Immutable) {
|
|
610
|
+
observerId = this.observeSharedValueBindDirect(pointerAddress, (update) => {
|
|
611
|
+
const [sourceId, ...data] = update;
|
|
539
612
|
// if source_id is not own transceiver id, handle pointer update
|
|
540
|
-
if (
|
|
613
|
+
if (sourceId !== __classPrivateFieldGet(this, _DIFHandler_transceiver_id, "f")) {
|
|
541
614
|
try {
|
|
542
|
-
this.handlePointerUpdate(pointerAddress, wrappedValue,
|
|
615
|
+
this.handlePointerUpdate(pointerAddress, wrappedValue, data, typeBinding);
|
|
543
616
|
}
|
|
544
617
|
catch (e) {
|
|
545
618
|
console.error("Error handling pointer update", e);
|
|
@@ -551,7 +624,7 @@ export class DIFHandler {
|
|
|
551
624
|
if (observers) {
|
|
552
625
|
for (const cb of observers.values()) {
|
|
553
626
|
try {
|
|
554
|
-
cb(
|
|
627
|
+
cb(data);
|
|
555
628
|
}
|
|
556
629
|
catch (e) {
|
|
557
630
|
console.error("Error in pointer observer callback", e);
|
|
@@ -561,7 +634,7 @@ export class DIFHandler {
|
|
|
561
634
|
console.debug("Pointer update received", update);
|
|
562
635
|
});
|
|
563
636
|
}
|
|
564
|
-
this.cacheWrappedReferenceValue(pointerAddress, value, wrappedValue, observerId, metadata);
|
|
637
|
+
this.cacheWrappedReferenceValue(pointerAddress, ownership, value, wrappedValue, observerId, metadata);
|
|
565
638
|
// set up observers
|
|
566
639
|
return wrappedValue;
|
|
567
640
|
}
|
|
@@ -572,8 +645,8 @@ export class DIFHandler {
|
|
|
572
645
|
const deref = cached.value.deref();
|
|
573
646
|
if (!deref)
|
|
574
647
|
return false;
|
|
575
|
-
if (deref instanceof
|
|
576
|
-
deref.updateValueSilently(this.
|
|
648
|
+
if (deref instanceof BaseSharedContainer && update[0] === DIFUpdateKind.Replace) {
|
|
649
|
+
deref.updateValueSilently(this.resolveDIFValueContainer(update[1]));
|
|
577
650
|
}
|
|
578
651
|
// handle generic updates for values (depending on type interface definition)
|
|
579
652
|
if (typeBinding) {
|
|
@@ -585,11 +658,12 @@ export class DIFHandler {
|
|
|
585
658
|
* Caches the given reference value with the given address in the JS side cache.
|
|
586
659
|
* The reference must already be wrapped if necessary.
|
|
587
660
|
*/
|
|
588
|
-
cacheWrappedReferenceValue(address, originalValue, proxiedValue, observerId, metadata = {}) {
|
|
661
|
+
cacheWrappedReferenceValue(address, ownership, originalValue, proxiedValue, observerId, metadata = {}) {
|
|
589
662
|
const isProxifiedValue = this.isWeakKey(originalValue) &&
|
|
590
663
|
originalValue !== proxiedValue;
|
|
591
664
|
__classPrivateFieldGet(this, _DIFHandler_cache, "f").set(address, {
|
|
592
665
|
value: new WeakRef(proxiedValue),
|
|
666
|
+
maxOwnership: ownership,
|
|
593
667
|
originalValue: isProxifiedValue ? originalValue : null,
|
|
594
668
|
observerId,
|
|
595
669
|
});
|
|
@@ -615,20 +689,33 @@ export class DIFHandler {
|
|
|
615
689
|
__classPrivateFieldGet(this, _DIFHandler_observers, "f").delete(address);
|
|
616
690
|
// if observer is active, unregister it
|
|
617
691
|
if (observerId !== null) {
|
|
618
|
-
this.
|
|
692
|
+
this.unobserveSharedValueBindDirect(address, observerId);
|
|
619
693
|
}
|
|
620
694
|
});
|
|
621
695
|
finalizationRegistry.register(proxiedValue, address);
|
|
622
696
|
}
|
|
623
|
-
|
|
697
|
+
getCachedStateForSharedContainer(address, ownership) {
|
|
698
|
+
if (!__classPrivateFieldGet(this, _DIFHandler_cache, "f").has(address)) {
|
|
699
|
+
return "not_cached";
|
|
700
|
+
}
|
|
624
701
|
const cached = __classPrivateFieldGet(this, _DIFHandler_cache, "f").get(address);
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
702
|
+
const deref = cached.value.deref();
|
|
703
|
+
if (!deref) {
|
|
704
|
+
throw new Error(`Cached reference for address ${address} is not dereferenceable`);
|
|
705
|
+
}
|
|
706
|
+
if (
|
|
707
|
+
// owership mismatch
|
|
708
|
+
(ownership === DIFSharedContainerOwnership.Owned &&
|
|
709
|
+
cached.maxOwnership !== DIFSharedContainerOwnership.Owned) || (cached.maxOwnership === DIFSharedContainerOwnership.Immutable &&
|
|
710
|
+
ownership === DIFSharedContainerOwnership.Mutable)) {
|
|
711
|
+
return "insufficient_ownership";
|
|
712
|
+
}
|
|
713
|
+
if (deref instanceof BaseSharedContainer) {
|
|
714
|
+
return deref.withOwnership(ownership);
|
|
715
|
+
}
|
|
716
|
+
else {
|
|
717
|
+
return deref;
|
|
630
718
|
}
|
|
631
|
-
return undefined;
|
|
632
719
|
}
|
|
633
720
|
/**
|
|
634
721
|
* Creates a new reference containg the given JS value.
|
|
@@ -636,19 +723,24 @@ export class DIFHandler {
|
|
|
636
723
|
* but also propagates changes between JS and the DATEX runtime.
|
|
637
724
|
* If a reference for the given value already exists, an error is thrown.
|
|
638
725
|
*/
|
|
639
|
-
|
|
640
|
-
// if already bound to a reference, return the existing reference proxy (or the value itself)
|
|
726
|
+
createSharedValueFromJSValue(value, allowedType = null, mutability = SharedContainerMutability.Mutable) {
|
|
641
727
|
const pointerAddress = this.getPointerAddressForValue(value);
|
|
642
728
|
if (pointerAddress) {
|
|
643
729
|
throw new Error(`Value is already bound to a reference ($${pointerAddress}). Cannot create a new reference for the same value.`);
|
|
644
730
|
}
|
|
645
731
|
const difValue = this.convertJSValueToDIFValueContainer(value);
|
|
646
|
-
const ptrAddress = this.
|
|
732
|
+
const ptrAddress = this.constructSharedValue(difValue, mutability, allowedType);
|
|
647
733
|
// get inferred allowed type from pointer if not explicitly set
|
|
648
734
|
if (!allowedType) {
|
|
649
|
-
allowedType = __classPrivateFieldGet(this, _DIFHandler_handle, "f").
|
|
735
|
+
allowedType = __classPrivateFieldGet(this, _DIFHandler_handle, "f").resolve_pointer_address(ptrAddress)[2];
|
|
736
|
+
}
|
|
737
|
+
const base = this.initSharedValue(ptrAddress, value, mutability, DIFSharedContainerOwnership.Owned, allowedType);
|
|
738
|
+
if (base instanceof BaseSharedContainer) {
|
|
739
|
+
return new OwnedSharedContainer(base);
|
|
740
|
+
}
|
|
741
|
+
else {
|
|
742
|
+
return base;
|
|
650
743
|
}
|
|
651
|
-
return this.initReference(ptrAddress, value, mutability, allowedType);
|
|
652
744
|
}
|
|
653
745
|
isPrimitiveValue(value) {
|
|
654
746
|
return value === null || value === undefined ||
|
|
@@ -664,17 +756,17 @@ export class DIFHandler {
|
|
|
664
756
|
/**
|
|
665
757
|
* Wraps a given JS value in a Ref proxy if necessary.
|
|
666
758
|
*/
|
|
667
|
-
wrapJSValue(value, pointerAddress, _type = null) {
|
|
759
|
+
wrapJSValue(value, pointerAddress, mutability, _type = null) {
|
|
668
760
|
// primitive values are always wrapped in a Ref proxy
|
|
669
761
|
if (this.isWeakKey(value)) {
|
|
670
762
|
return value;
|
|
671
763
|
}
|
|
672
764
|
else {
|
|
673
|
-
return new
|
|
765
|
+
return new BaseSharedContainer(value, pointerAddress, mutability, this);
|
|
674
766
|
}
|
|
675
767
|
}
|
|
676
|
-
|
|
677
|
-
return value instanceof
|
|
768
|
+
isBaseSharedContainer(value) {
|
|
769
|
+
return value instanceof BaseSharedContainer;
|
|
678
770
|
}
|
|
679
771
|
wrapJSObjectInProxy(value) {
|
|
680
772
|
// deno-lint-ignore no-this-alias
|
|
@@ -682,14 +774,14 @@ export class DIFHandler {
|
|
|
682
774
|
return new Proxy(value, {
|
|
683
775
|
get(target, prop, receiver) {
|
|
684
776
|
const val = Reflect.get(target, prop, receiver);
|
|
685
|
-
if (val && typeof val === "object" && !self.
|
|
777
|
+
if (val && typeof val === "object" && !self.isBaseSharedContainer(val)) {
|
|
686
778
|
return self.wrapJSObjectInProxy(val);
|
|
687
779
|
}
|
|
688
780
|
return val;
|
|
689
781
|
},
|
|
690
782
|
set(target, prop, newValue, receiver) {
|
|
691
783
|
const oldValue = Reflect.get(target, prop, receiver);
|
|
692
|
-
if (!self.
|
|
784
|
+
if (!self.isBaseSharedContainer(oldValue)) {
|
|
693
785
|
throw new Error(`Cannot modify non-Ref property "${String(prop)}"`);
|
|
694
786
|
}
|
|
695
787
|
oldValue.value = newValue;
|
|
@@ -729,101 +821,96 @@ export class DIFHandler {
|
|
|
729
821
|
__classPrivateFieldGet(this, _DIFHandler_referenceMetadata, "f").get(__classPrivateFieldGet(this, _DIFHandler_proxyMapping, "f").get(value)?.deref()) ??
|
|
730
822
|
null);
|
|
731
823
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
}
|
|
824
|
+
// FIXME do we need these two methods still?
|
|
825
|
+
// public isReference(value: object): boolean {
|
|
826
|
+
// return this.#referenceMetadata.has(value as CachedSharedContainer) ||
|
|
827
|
+
// this.#proxyMapping.has(value);
|
|
828
|
+
// }
|
|
829
|
+
// public getReferenceProxy<T>(value: CachedSharedContainer<T>): T | null {
|
|
830
|
+
// const reference = this.#referenceMetadata.get(value);
|
|
831
|
+
// if (reference) {
|
|
832
|
+
// return value;
|
|
833
|
+
// }
|
|
834
|
+
// const proxyRef = this.#proxyMapping.get(value);
|
|
835
|
+
// if (proxyRef) {
|
|
836
|
+
// const deref = proxyRef.deref();
|
|
837
|
+
// if (deref) {
|
|
838
|
+
// return deref as T;
|
|
839
|
+
// } else {
|
|
840
|
+
// panic("Reference proxy has been garbage collected");
|
|
841
|
+
// }
|
|
842
|
+
// } else {
|
|
843
|
+
// return null;
|
|
844
|
+
// }
|
|
845
|
+
// }
|
|
755
846
|
/**
|
|
756
847
|
* Converts a given JS value to its DIFValueContainer representation.
|
|
757
848
|
* This method can be called statically or with an instance to use the instance's DIFHandler context.
|
|
758
849
|
* NOTE: When called statically, there is no cache for already registered references, meaning that new references will be created
|
|
759
850
|
* for the same object each time this method is called.
|
|
760
851
|
*/
|
|
761
|
-
static convertJSValueToDIFValueContainer(value, difHandlerInstance) {
|
|
852
|
+
static convertJSValueToDIFValueContainer(value, difHandlerInstance, forceExplicitFormat = false) {
|
|
762
853
|
// if the value is a registered reference, return its address
|
|
763
854
|
const existingReference = difHandlerInstance &&
|
|
764
855
|
difHandlerInstance.tryGetReferenceMetadata(value);
|
|
765
856
|
if (existingReference) {
|
|
766
|
-
|
|
857
|
+
const ownership = __classPrivateFieldGet(difHandlerInstance, _DIFHandler_cache, "f").get(existingReference.address);
|
|
858
|
+
if (!ownership) {
|
|
859
|
+
throw new Error(`Reference metadata found for address ${existingReference.address} but no ownership info in cache`);
|
|
860
|
+
}
|
|
861
|
+
// move(x) -> function (x: OwnedValue) {}
|
|
862
|
+
return { $: combinePointerAddressWithOwnership(existingReference.address, ownership.maxOwnership) };
|
|
767
863
|
}
|
|
768
|
-
// assuming core values
|
|
769
864
|
// TODO: handle custom types
|
|
770
865
|
if (value === null) {
|
|
771
|
-
return
|
|
772
|
-
value: null,
|
|
773
|
-
};
|
|
866
|
+
return forceExplicitFormat ? [CoreLibTypeId.null, null] : null;
|
|
774
867
|
}
|
|
775
868
|
else if (value === undefined) {
|
|
776
|
-
return
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
CoreTypeAddress.null,
|
|
781
|
-
[JsLibTypeAddress.undefined],
|
|
782
|
-
],
|
|
783
|
-
},
|
|
784
|
-
value: null,
|
|
785
|
-
};
|
|
869
|
+
return JS_UNDEFINED;
|
|
870
|
+
}
|
|
871
|
+
else if (typeof value === "string") {
|
|
872
|
+
return forceExplicitFormat ? [CoreLibTypeId.text, value] : value;
|
|
786
873
|
}
|
|
787
874
|
else if (typeof value === "boolean") {
|
|
788
|
-
return
|
|
789
|
-
value,
|
|
790
|
-
};
|
|
875
|
+
return forceExplicitFormat ? [CoreLibTypeId.boolean, value] : value;
|
|
791
876
|
}
|
|
792
877
|
else if (typeof value === "number") {
|
|
793
|
-
return
|
|
794
|
-
value,
|
|
795
|
-
};
|
|
878
|
+
return forceExplicitFormat ? [CoreLibTypeId.decimal_f64, value] : value;
|
|
796
879
|
}
|
|
797
880
|
else if (typeof value === "bigint") {
|
|
798
|
-
return
|
|
799
|
-
type: CoreTypeAddress.integer_ibig,
|
|
800
|
-
value: value.toString(), // convert bigint to string for DIFValue
|
|
801
|
-
};
|
|
802
|
-
}
|
|
803
|
-
else if (typeof value === "string") {
|
|
804
|
-
return {
|
|
805
|
-
value,
|
|
806
|
-
};
|
|
881
|
+
return ibig(value);
|
|
807
882
|
}
|
|
808
883
|
else if (value instanceof Endpoint) {
|
|
809
|
-
return
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
884
|
+
return [CoreLibTypeId.endpoint, value.toString()];
|
|
885
|
+
}
|
|
886
|
+
else if (value instanceof Tagged) {
|
|
887
|
+
// special case: empty tagged value
|
|
888
|
+
if (value.value === EMPTY_TAG) {
|
|
889
|
+
return [CoreLibTypeId.null, null, {
|
|
890
|
+
tagged_type: [value.tag, CoreLibTypeId.Unit],
|
|
891
|
+
}];
|
|
892
|
+
}
|
|
893
|
+
const inner = this.convertJSValueToDIFValueContainer(value.value, difHandlerInstance, true);
|
|
894
|
+
if (inner instanceof Array) {
|
|
895
|
+
return [inner[0], inner[1], {
|
|
896
|
+
tagged_type: [value.tag, inner[2] || inner[0]], // TODO: nullable type
|
|
897
|
+
}];
|
|
898
|
+
}
|
|
899
|
+
else if (typeof inner === "object" && inner !== null) {
|
|
900
|
+
unimplemented("Support nested shared reference value in tagged value");
|
|
901
|
+
}
|
|
902
|
+
else {
|
|
903
|
+
unreachable("convertJSValueToDIFValueContainer with forceExplicitFormat should return an array or object");
|
|
904
|
+
}
|
|
813
905
|
}
|
|
814
906
|
else if (value instanceof Range) {
|
|
815
|
-
return
|
|
816
|
-
type: CoreTypeAddress.range,
|
|
817
|
-
value: [
|
|
907
|
+
return [CoreLibTypeId.Range, [
|
|
818
908
|
this.convertJSValueToDIFValueContainer(value.start),
|
|
819
909
|
this.convertJSValueToDIFValueContainer(value.end),
|
|
820
|
-
]
|
|
821
|
-
};
|
|
910
|
+
]];
|
|
822
911
|
}
|
|
823
912
|
else if (Array.isArray(value)) {
|
|
824
|
-
return
|
|
825
|
-
value: value.map((v) => this.convertJSValueToDIFValueContainer(v)),
|
|
826
|
-
};
|
|
913
|
+
return [CoreLibTypeId.List, value.map((v) => this.convertJSValueToDIFValueContainer(v))];
|
|
827
914
|
}
|
|
828
915
|
else if (value instanceof Map) {
|
|
829
916
|
const map = value
|
|
@@ -831,19 +918,16 @@ export class DIFHandler {
|
|
|
831
918
|
this.convertJSValueToDIFValueContainer(k),
|
|
832
919
|
this.convertJSValueToDIFValueContainer(v),
|
|
833
920
|
]).toArray();
|
|
834
|
-
return {
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
};
|
|
921
|
+
return [CoreLibTypeId.Map, map, {
|
|
922
|
+
impl_type: [CoreLibTypeId.Map, [JsLibTypeAddress.map]],
|
|
923
|
+
}];
|
|
838
924
|
}
|
|
839
925
|
else if (typeof value === "object") {
|
|
840
926
|
const map = {};
|
|
841
927
|
for (const [key, val] of Object.entries(value)) {
|
|
842
928
|
map[key] = this.convertJSValueToDIFValueContainer(val);
|
|
843
929
|
}
|
|
844
|
-
return
|
|
845
|
-
value: map,
|
|
846
|
-
};
|
|
930
|
+
return [CoreLibTypeId.Map, map];
|
|
847
931
|
}
|
|
848
932
|
throw new Error("Unsupported type for conversion to DIFValue");
|
|
849
933
|
}
|
|
@@ -862,13 +946,7 @@ export class DIFHandler {
|
|
|
862
946
|
triggerSet(pointerAddress, key, value) {
|
|
863
947
|
const difKey = this.convertJSValueToDIFValueContainer(key);
|
|
864
948
|
const difValue = this.convertJSValueToDIFValueContainer(value);
|
|
865
|
-
|
|
866
|
-
kind: DIFUpdateKind.Set,
|
|
867
|
-
key: { kind: "value", value: difKey },
|
|
868
|
-
value: difValue,
|
|
869
|
-
};
|
|
870
|
-
console.log("Triggering set update", update);
|
|
871
|
-
this.updateReference(pointerAddress, update);
|
|
949
|
+
this.updateSharedValue(pointerAddress, setEntry(createDIFProperty(difKey, DIFPropertyKind.ValueContainer), difValue));
|
|
872
950
|
}
|
|
873
951
|
/**
|
|
874
952
|
* Triggers a 'set' update for the given pointer address, index and value.
|
|
@@ -878,73 +956,41 @@ export class DIFHandler {
|
|
|
878
956
|
throw new Error("Index must be a non-negative integer");
|
|
879
957
|
}
|
|
880
958
|
const difValue = this.convertJSValueToDIFValueContainer(value);
|
|
881
|
-
|
|
882
|
-
kind: DIFUpdateKind.Set,
|
|
883
|
-
key: { kind: "index", value: Number(index) },
|
|
884
|
-
value: difValue,
|
|
885
|
-
};
|
|
886
|
-
console.log("Triggering index set update", update);
|
|
887
|
-
this.updateReference(pointerAddress, update);
|
|
959
|
+
this.updateSharedValue(pointerAddress, setEntry(createDIFProperty(Number(index), DIFPropertyKind.Index), difValue));
|
|
888
960
|
}
|
|
889
961
|
/**
|
|
890
962
|
* Triggers an 'append' update for the given pointer address and value.
|
|
891
963
|
*/
|
|
892
964
|
triggerAppend(pointerAddress, value) {
|
|
893
965
|
const difValue = this.convertJSValueToDIFValueContainer(value);
|
|
894
|
-
|
|
895
|
-
kind: DIFUpdateKind.Append,
|
|
896
|
-
value: difValue,
|
|
897
|
-
};
|
|
898
|
-
console.log("Triggering append update", update);
|
|
899
|
-
this.updateReference(pointerAddress, update);
|
|
966
|
+
this.updateSharedValue(pointerAddress, appendEntry(difValue));
|
|
900
967
|
}
|
|
901
968
|
/**
|
|
902
969
|
* Triggers a 'replace' update for the given pointer address and key.
|
|
903
970
|
*/
|
|
904
971
|
triggerReplace(pointerAddress, value) {
|
|
905
972
|
const difValue = this.convertJSValueToDIFValueContainer(value);
|
|
906
|
-
|
|
907
|
-
kind: DIFUpdateKind.Replace,
|
|
908
|
-
value: difValue,
|
|
909
|
-
};
|
|
910
|
-
console.log("Triggering replace update", update);
|
|
911
|
-
this.updateReference(pointerAddress, update);
|
|
973
|
+
this.updateSharedValue(pointerAddress, replace(difValue));
|
|
912
974
|
}
|
|
913
975
|
/**
|
|
914
976
|
* Triggers a 'delete' update for the given pointer address and key.
|
|
915
977
|
*/
|
|
916
978
|
triggerDelete(pointerAddress, key) {
|
|
917
979
|
const difKey = this.convertJSValueToDIFValueContainer(key);
|
|
918
|
-
|
|
919
|
-
kind: DIFUpdateKind.Delete,
|
|
920
|
-
key: { kind: "value", value: difKey },
|
|
921
|
-
};
|
|
922
|
-
console.log("Triggering delete update", update);
|
|
923
|
-
this.updateReference(pointerAddress, update);
|
|
980
|
+
this.updateSharedValue(pointerAddress, deleteEntry(createDIFProperty(difKey, DIFPropertyKind.ValueContainer)));
|
|
924
981
|
}
|
|
925
982
|
/**
|
|
926
983
|
* Triggers a 'clear' update for the given pointer address.
|
|
927
984
|
*/
|
|
928
985
|
triggerClear(pointerAddress) {
|
|
929
|
-
|
|
930
|
-
kind: DIFUpdateKind.Clear,
|
|
931
|
-
};
|
|
932
|
-
console.log("Triggering clear update", update);
|
|
933
|
-
this.updateReference(pointerAddress, update);
|
|
986
|
+
this.updateSharedValue(pointerAddress, clear());
|
|
934
987
|
}
|
|
935
988
|
/**
|
|
936
989
|
* Triggers a 'list splice' update for the given pointer address.
|
|
937
990
|
*/
|
|
938
991
|
triggerListSplice(pointerAddress, start, deleteCount, items) {
|
|
939
992
|
const difItems = items.map((item) => this.convertJSValueToDIFValueContainer(item));
|
|
940
|
-
|
|
941
|
-
kind: DIFUpdateKind.ListSplice,
|
|
942
|
-
start,
|
|
943
|
-
delete_count: deleteCount,
|
|
944
|
-
items: difItems,
|
|
945
|
-
};
|
|
946
|
-
console.log("Triggering list splice update", update);
|
|
947
|
-
this.updateReference(pointerAddress, update);
|
|
993
|
+
this.updateSharedValue(pointerAddress, listSplice(start, deleteCount, difItems));
|
|
948
994
|
}
|
|
949
995
|
}
|
|
950
996
|
_DIFHandler_runtime = new WeakMap(), _DIFHandler_handle = new WeakMap(), _DIFHandler_transceiver_id = new WeakMap(), _DIFHandler_cache = new WeakMap(), _DIFHandler_proxyMapping = new WeakMap(), _DIFHandler_referenceMetadata = new WeakMap(), _DIFHandler_observers = new WeakMap(), _DIFHandler_type_registry = new WeakMap();
|