@unyt/datex 0.0.13 → 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 +221 -188
- package/esm/datex-web/datex_web.internal.d.ts.map +1 -1
- package/esm/datex-web/datex_web.internal.js +453 -385
- 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 -39
- package/esm/dif/core.d.ts.map +1 -1
- package/esm/dif/core.js +33 -53
- 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 +417 -345
- 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/endpoint.d.ts.map +1 -1
- 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/range.d.ts +26 -0
- package/esm/lib/special-core-types/range.d.ts.map +1 -0
- package/esm/lib/special-core-types/range.js +46 -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 +3 -1
- package/esm/mod.d.ts.map +1 -1
- package/esm/mod.js +3 -1
- 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.d.ts +8 -0
- package/esm/repl/mod.d.ts.map +1 -0
- package/esm/repl/mod.js +31 -0
- 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 +24 -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,13 +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
|
-
import {
|
|
16
|
-
import {
|
|
18
|
+
import { Range } from "../lib/special-core-types/range.js";
|
|
19
|
+
import { DIFUpdateKind, } from "./types/mod.js";
|
|
20
|
+
import { CoreLibTypeId } from "./core.js";
|
|
17
21
|
import { TypeRegistry } from "./type-registry.js";
|
|
18
|
-
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";
|
|
19
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
|
+
}
|
|
20
79
|
export const IS_PROXY_ACCESS = Symbol("IS_PROXY_ACCESS");
|
|
21
80
|
/**
|
|
22
81
|
* The DIFHandler class provides methods to interact with the DATEX Core DIF runtime,
|
|
@@ -33,7 +92,7 @@ export class DIFHandler {
|
|
|
33
92
|
}
|
|
34
93
|
/**
|
|
35
94
|
* Internal property
|
|
36
|
-
* @returns The
|
|
95
|
+
* @returns The {@link JSDIFInterface} instance.
|
|
37
96
|
*/
|
|
38
97
|
get _handle() {
|
|
39
98
|
return __classPrivateFieldGet(this, _DIFHandler_handle, "f");
|
|
@@ -51,7 +110,6 @@ export class DIFHandler {
|
|
|
51
110
|
/**
|
|
52
111
|
* Creates a new DIFHandler instance.
|
|
53
112
|
* @param runtime - The JSRuntime instance for executing Datex scripts.
|
|
54
|
-
* @param pointerCache - The PointerCache instance for managing object pointers. If not provided, a new PointerCache will be created.
|
|
55
113
|
*/
|
|
56
114
|
constructor(runtime) {
|
|
57
115
|
/** The JSRuntime interface for the underlying Datex Core runtime */
|
|
@@ -76,7 +134,7 @@ export class DIFHandler {
|
|
|
76
134
|
_DIFHandler_observers.set(this, new Map());
|
|
77
135
|
_DIFHandler_type_registry.set(this, new TypeRegistry(this));
|
|
78
136
|
__classPrivateFieldSet(this, _DIFHandler_runtime, runtime, "f");
|
|
79
|
-
__classPrivateFieldSet(this, _DIFHandler_handle, runtime.
|
|
137
|
+
__classPrivateFieldSet(this, _DIFHandler_handle, runtime.dif_interface(), "f");
|
|
80
138
|
}
|
|
81
139
|
/**
|
|
82
140
|
* Executes a Datex script asynchronously and returns a Promise that resolves to a DIFContainer.
|
|
@@ -85,8 +143,8 @@ export class DIFHandler {
|
|
|
85
143
|
* @returns A Promise that resolves to the execution result as a DIFContainer.
|
|
86
144
|
* @throws If an error occurs during execution.
|
|
87
145
|
*/
|
|
88
|
-
executeDIF(datexScript, values = []) {
|
|
89
|
-
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)));
|
|
90
148
|
}
|
|
91
149
|
/**
|
|
92
150
|
* Executes a Datex script synchronously and returns the result as a DIFContainer.
|
|
@@ -96,7 +154,7 @@ export class DIFHandler {
|
|
|
96
154
|
* @throws If an error occurs during execution.
|
|
97
155
|
*/
|
|
98
156
|
executeSyncDIF(datexScript, values = []) {
|
|
99
|
-
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)));
|
|
100
158
|
}
|
|
101
159
|
/**
|
|
102
160
|
* Creates a new shared value for the specified DIF value.
|
|
@@ -105,16 +163,23 @@ export class DIFHandler {
|
|
|
105
163
|
* @param mutability - The mutability of the pointer.
|
|
106
164
|
* @returns The created pointer address.
|
|
107
165
|
*/
|
|
108
|
-
|
|
109
|
-
|
|
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);
|
|
110
175
|
}
|
|
111
176
|
/**
|
|
112
177
|
* Updates the DIF value at the specified address.
|
|
113
178
|
* @param address - The address of the DIF value to update.
|
|
114
|
-
* @param
|
|
179
|
+
* @param update_data - The DIFUpdate object containing the update information.
|
|
115
180
|
*/
|
|
116
|
-
|
|
117
|
-
__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]);
|
|
118
183
|
}
|
|
119
184
|
/**
|
|
120
185
|
* Registers an observer callback for changes to the DIF value at the specified address
|
|
@@ -127,8 +192,8 @@ export class DIFHandler {
|
|
|
127
192
|
* @returns An observer ID that can be used to unregister the observer.
|
|
128
193
|
* @throws If the pointer is final.
|
|
129
194
|
*/
|
|
130
|
-
|
|
131
|
-
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);
|
|
132
197
|
}
|
|
133
198
|
/**
|
|
134
199
|
* Updates the observe options for a registered observer.
|
|
@@ -137,7 +202,7 @@ export class DIFHandler {
|
|
|
137
202
|
* @param options - The new observe options to apply.
|
|
138
203
|
*/
|
|
139
204
|
updateObserverOptions(address, observerId, options) {
|
|
140
|
-
__classPrivateFieldGet(this, _DIFHandler_runtime, "f").
|
|
205
|
+
__classPrivateFieldGet(this, _DIFHandler_runtime, "f").dif_interface().update_observer_options(address, observerId, options);
|
|
141
206
|
}
|
|
142
207
|
/**
|
|
143
208
|
* Enables propagation of own updates for a registered observer.
|
|
@@ -166,8 +231,8 @@ export class DIFHandler {
|
|
|
166
231
|
* @param address - The address of the DIF value being observed.
|
|
167
232
|
* @param observerId - The observer ID returned by the observePointer method.
|
|
168
233
|
*/
|
|
169
|
-
|
|
170
|
-
__classPrivateFieldGet(this, _DIFHandler_runtime, "f").
|
|
234
|
+
unobserveSharedValueBindDirect(address, observerId) {
|
|
235
|
+
__classPrivateFieldGet(this, _DIFHandler_runtime, "f").dif_interface().unobserve_pointer(address, observerId);
|
|
171
236
|
}
|
|
172
237
|
/**
|
|
173
238
|
* Registers a local observer callback for changes to the DIF value at the specified address.
|
|
@@ -184,7 +249,7 @@ export class DIFHandler {
|
|
|
184
249
|
let cached = __classPrivateFieldGet(this, _DIFHandler_cache, "f").get(address);
|
|
185
250
|
if (!cached) {
|
|
186
251
|
// first resolve the pointer to make sure it's loaded in the cache
|
|
187
|
-
this.
|
|
252
|
+
this.resolvePointerAddress(DIFSharedContainerOwnership.Immutable, address);
|
|
188
253
|
cached = __classPrivateFieldGet(this, _DIFHandler_cache, "f").get(address);
|
|
189
254
|
}
|
|
190
255
|
// make sure the pointer is not final (no observer)
|
|
@@ -235,131 +300,176 @@ export class DIFHandler {
|
|
|
235
300
|
* @param value
|
|
236
301
|
*/
|
|
237
302
|
resolveDIFValue(value) {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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");
|
|
329
|
+
}
|
|
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");
|
|
335
|
+
}
|
|
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);
|
|
250
386
|
}
|
|
251
|
-
else if (typeof value.value === "object" && value.value !== null) {
|
|
252
|
-
type = CoreTypeAddress.map;
|
|
253
|
-
convertMapToJSObject = true;
|
|
254
|
-
} // primitive JS value, no type specified
|
|
255
387
|
else {
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
return Number(value.value);
|
|
269
|
-
} // big integers are interpreted as JS BigInt
|
|
270
|
-
else if (typeof type === "string" && (this.isPointerAddressInAdresses(type, CoreTypeAddressRanges.big_signed_integers))) {
|
|
271
|
-
return BigInt(value.value);
|
|
272
|
-
} // decimal types are interpreted as JS numbers
|
|
273
|
-
else if (typeof type === "string" &&
|
|
274
|
-
this.isPointerAddressInAdresses(type, CoreTypeAddressRanges.decimals)) {
|
|
275
|
-
return Number(value.value);
|
|
276
|
-
} // endpoint types are resolved to Endpoint instances
|
|
277
|
-
else if (type === CoreTypeAddress.endpoint) {
|
|
278
|
-
return Endpoint.get(value.value);
|
|
279
|
-
}
|
|
280
|
-
else if (type === CoreTypeAddress.list) {
|
|
281
|
-
return this.promiseAllOrSync(value.value.map((v) => this.resolveDIFValueContainer(v)));
|
|
282
|
-
} // map types are resolved from a DIFObject (aka JS Map) or Array of key-value pairs to a JS object
|
|
283
|
-
else if (type === CoreTypeAddress.map) {
|
|
284
|
-
if (Array.isArray(value.value)) {
|
|
285
|
-
const resolvedMap = new Map();
|
|
286
|
-
for (const [key, val] of value.value) {
|
|
287
|
-
resolvedMap.set(this.resolveDIFValueContainer(key), this.resolveDIFValueContainer(val));
|
|
288
|
-
}
|
|
289
|
-
// TODO: map promises
|
|
290
|
-
return resolvedMap;
|
|
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);
|
|
397
|
+
}
|
|
398
|
+
else if (typeof core === "number") {
|
|
399
|
+
val = core;
|
|
291
400
|
}
|
|
292
401
|
else {
|
|
293
|
-
|
|
294
|
-
const resolvedObj = {};
|
|
295
|
-
for (const [key, val] of Object.entries(value.value)) {
|
|
296
|
-
resolvedObj[key] = this.resolveDIFValueContainer(val);
|
|
297
|
-
}
|
|
298
|
-
return resolvedObj;
|
|
299
|
-
}
|
|
300
|
-
else {
|
|
301
|
-
const resolvedMap = new Map();
|
|
302
|
-
for (const [key, val] of Object.entries(value.value)) {
|
|
303
|
-
resolvedMap.set(key, this.resolveDIFValueContainer(val));
|
|
304
|
-
}
|
|
305
|
-
return resolvedMap;
|
|
306
|
-
}
|
|
402
|
+
throw new Error("Expected number value for decimal type");
|
|
307
403
|
}
|
|
308
|
-
}
|
|
309
|
-
else if (
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
if (type.def[0] === CoreTypeAddress.null &&
|
|
313
|
-
type.def[1].length === 1 &&
|
|
314
|
-
type.def[1][0] == JsLibTypeAddress.undefined) {
|
|
315
|
-
return undefined;
|
|
404
|
+
}
|
|
405
|
+
else if (type === CoreLibTypeId.text) {
|
|
406
|
+
if (typeof core !== "string") {
|
|
407
|
+
throw new Error("Expected string value for text type");
|
|
316
408
|
}
|
|
409
|
+
val = core;
|
|
317
410
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
* or an array of resolved values if all values are already resolved.
|
|
324
|
-
*/
|
|
325
|
-
promiseAllOrSync(values) {
|
|
326
|
-
if (values.some((v) => v instanceof Promise)) {
|
|
327
|
-
return Promise.all(values);
|
|
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);
|
|
328
416
|
}
|
|
329
|
-
else {
|
|
330
|
-
|
|
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]);
|
|
428
|
+
}
|
|
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));
|
|
331
434
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
promiseFromObjectOrSync(values) {
|
|
338
|
-
const valueArray = Object.values(values);
|
|
339
|
-
if (valueArray.some((v) => v instanceof Promise)) {
|
|
340
|
-
return Promise.all(valueArray).then((resolvedValues) => {
|
|
341
|
-
const resolvedObj = {};
|
|
342
|
-
let i = 0;
|
|
343
|
-
for (const key of Object.keys(values)) {
|
|
344
|
-
resolvedObj[key] = resolvedValues[i++];
|
|
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));
|
|
345
440
|
}
|
|
346
|
-
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
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
|
+
}
|
|
359
456
|
}
|
|
360
|
-
|
|
361
|
-
|
|
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
|
+
}
|
|
362
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");
|
|
363
473
|
}
|
|
364
474
|
/**
|
|
365
475
|
* Resolves a DIFValueContainer (either a DIFValue or a pointer address) to its corresponding JS value.
|
|
@@ -369,41 +479,27 @@ export class DIFHandler {
|
|
|
369
479
|
* @returns The resolved value as type T, or a Promise that resolves to type T.
|
|
370
480
|
*/
|
|
371
481
|
resolveDIFValueContainer(value) {
|
|
372
|
-
if (typeof value !== "
|
|
373
|
-
return this.
|
|
482
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value) && "$" in value) {
|
|
483
|
+
return this.resolvePointerAddress(...splitPointerAddressWithOwnership(value.$));
|
|
374
484
|
}
|
|
375
485
|
else {
|
|
376
|
-
return this.
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
/**
|
|
380
|
-
* Synchronous version of resolveDIFValueContainer.
|
|
381
|
-
* This method can only be used if the value only contains pointer addresses that are already loaded in memory -
|
|
382
|
-
* otherwise, use the asynchronous `resolveDIFValueContainer` method instead.
|
|
383
|
-
* @param value - The DIFValueContainer to resolve.
|
|
384
|
-
* @returns The resolved value as type T.
|
|
385
|
-
* @throws If the resolution would require asynchronous operations.
|
|
386
|
-
*/
|
|
387
|
-
resolveDIFValueContainerSync(value) {
|
|
388
|
-
const result = this.resolveDIFValueContainer(value);
|
|
389
|
-
if (result instanceof Promise) {
|
|
390
|
-
throw new Error("resolveDIFValueContainerSync cannot return a Promise. Use resolveDIFValueContainer() instead.");
|
|
486
|
+
return this.resolveDIFValue(value);
|
|
391
487
|
}
|
|
392
|
-
return result;
|
|
393
488
|
}
|
|
394
489
|
/**
|
|
395
490
|
* Resolves a DIFProperty to its corresponding JS value.
|
|
396
491
|
*/
|
|
397
|
-
|
|
398
|
-
if (property
|
|
399
|
-
return property
|
|
492
|
+
resolveDIFProperty(property) {
|
|
493
|
+
if (typeof property === "number") {
|
|
494
|
+
return property;
|
|
400
495
|
}
|
|
401
|
-
|
|
402
|
-
return property
|
|
496
|
+
if (typeof property === "string") {
|
|
497
|
+
return property;
|
|
403
498
|
}
|
|
404
|
-
|
|
405
|
-
return this.
|
|
499
|
+
if (typeof property === "object" && property !== null && !Array.isArray(property) && "value" in property) {
|
|
500
|
+
return this.resolveDIFValueContainer(property.value);
|
|
406
501
|
}
|
|
502
|
+
throw new Error("Invalid DIFProperty format");
|
|
407
503
|
}
|
|
408
504
|
/**
|
|
409
505
|
* Resolves a pointer address to its corresponding JS value.
|
|
@@ -412,43 +508,33 @@ export class DIFHandler {
|
|
|
412
508
|
* @param address - The pointer address to resolve.
|
|
413
509
|
* @returns The resolved value as type T, or a Promise that resolves to type T.
|
|
414
510
|
*/
|
|
415
|
-
resolvePointerAddress(address) {
|
|
511
|
+
resolvePointerAddress(ownership, address) {
|
|
512
|
+
const addressWithOwnership = combinePointerAddressWithOwnership(address, ownership);
|
|
416
513
|
// check cache first
|
|
417
|
-
const cached = this.
|
|
418
|
-
if (cached) {
|
|
419
|
-
|
|
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;
|
|
420
526
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
const value = this.resolveDIFValueContainer(
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
/**
|
|
433
|
-
* Resolves a pointer address to its corresponding JS value synchronously.
|
|
434
|
-
* If the pointer address is not yet loaded in memory, it returns a Promise that resolves to the value.
|
|
435
|
-
* Otherwise, it returns the resolved value directly.
|
|
436
|
-
* @param address - The pointer address to resolve.
|
|
437
|
-
* @returns The resolved value as type T, or a Promise that resolves to type T.
|
|
438
|
-
* @throws If the resolution would require asynchronous operations.
|
|
439
|
-
*/
|
|
440
|
-
resolvePointerAddressSync(address) {
|
|
441
|
-
// check cache first
|
|
442
|
-
const cached = this.getCachedReference(address);
|
|
443
|
-
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
|
|
444
536
|
return cached;
|
|
445
537
|
}
|
|
446
|
-
// if not in cache, resolve from runtime
|
|
447
|
-
const entry = __classPrivateFieldGet(this, _DIFHandler_handle, "f")
|
|
448
|
-
.resolve_pointer_address_sync(address);
|
|
449
|
-
const value = this.resolveDIFValueContainerSync(entry.value);
|
|
450
|
-
this.initReference(address, value, entry.mut, entry.allowed_type);
|
|
451
|
-
return value;
|
|
452
538
|
}
|
|
453
539
|
/**
|
|
454
540
|
* Retrieves the original value from a proxy value if available
|
|
@@ -489,25 +575,28 @@ export class DIFHandler {
|
|
|
489
575
|
return values?.map((value) => this.convertJSValueToDIFValueContainer(value)) ||
|
|
490
576
|
null;
|
|
491
577
|
}
|
|
492
|
-
/**
|
|
493
|
-
* Returns true if the given address is within the specified address range.
|
|
494
|
-
*/
|
|
495
|
-
isPointerAddressInAdresses(address, range) {
|
|
496
|
-
return range.has(address);
|
|
497
|
-
}
|
|
498
578
|
/**
|
|
499
579
|
* Initializes a reference with the given value and mutability, by
|
|
500
580
|
* adding a proxy wrapper if necessary, and setting up observation and caching on the JS side.
|
|
501
581
|
*/
|
|
502
|
-
|
|
503
|
-
let wrappedValue = this.wrapJSValue(value, pointerAddress, allowedType);
|
|
582
|
+
initSharedValue(pointerAddress, value, mutability, ownership, allowedType) {
|
|
583
|
+
let wrappedValue = this.wrapJSValue(value, pointerAddress, mutability, allowedType);
|
|
504
584
|
let typeBinding = null;
|
|
505
585
|
let metadata = undefined;
|
|
506
586
|
// bind js value (if mutable, nominal type)
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
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
|
|
511
600
|
if (typeBinding) {
|
|
512
601
|
const { value, metadata: newMetadata } = typeBinding
|
|
513
602
|
.bindValue(wrappedValue, pointerAddress);
|
|
@@ -517,12 +606,13 @@ export class DIFHandler {
|
|
|
517
606
|
}
|
|
518
607
|
// if not immutable, observe to keep the pointer 'live' and receive updates
|
|
519
608
|
let observerId = null;
|
|
520
|
-
if (mutability !==
|
|
521
|
-
observerId = this.
|
|
609
|
+
if (mutability !== SharedContainerMutability.Immutable) {
|
|
610
|
+
observerId = this.observeSharedValueBindDirect(pointerAddress, (update) => {
|
|
611
|
+
const [sourceId, ...data] = update;
|
|
522
612
|
// if source_id is not own transceiver id, handle pointer update
|
|
523
|
-
if (
|
|
613
|
+
if (sourceId !== __classPrivateFieldGet(this, _DIFHandler_transceiver_id, "f")) {
|
|
524
614
|
try {
|
|
525
|
-
this.handlePointerUpdate(pointerAddress, wrappedValue,
|
|
615
|
+
this.handlePointerUpdate(pointerAddress, wrappedValue, data, typeBinding);
|
|
526
616
|
}
|
|
527
617
|
catch (e) {
|
|
528
618
|
console.error("Error handling pointer update", e);
|
|
@@ -534,7 +624,7 @@ export class DIFHandler {
|
|
|
534
624
|
if (observers) {
|
|
535
625
|
for (const cb of observers.values()) {
|
|
536
626
|
try {
|
|
537
|
-
cb(
|
|
627
|
+
cb(data);
|
|
538
628
|
}
|
|
539
629
|
catch (e) {
|
|
540
630
|
console.error("Error in pointer observer callback", e);
|
|
@@ -544,7 +634,7 @@ export class DIFHandler {
|
|
|
544
634
|
console.debug("Pointer update received", update);
|
|
545
635
|
});
|
|
546
636
|
}
|
|
547
|
-
this.cacheWrappedReferenceValue(pointerAddress, value, wrappedValue, observerId, metadata);
|
|
637
|
+
this.cacheWrappedReferenceValue(pointerAddress, ownership, value, wrappedValue, observerId, metadata);
|
|
548
638
|
// set up observers
|
|
549
639
|
return wrappedValue;
|
|
550
640
|
}
|
|
@@ -555,8 +645,8 @@ export class DIFHandler {
|
|
|
555
645
|
const deref = cached.value.deref();
|
|
556
646
|
if (!deref)
|
|
557
647
|
return false;
|
|
558
|
-
if (deref instanceof
|
|
559
|
-
deref.updateValueSilently(this.
|
|
648
|
+
if (deref instanceof BaseSharedContainer && update[0] === DIFUpdateKind.Replace) {
|
|
649
|
+
deref.updateValueSilently(this.resolveDIFValueContainer(update[1]));
|
|
560
650
|
}
|
|
561
651
|
// handle generic updates for values (depending on type interface definition)
|
|
562
652
|
if (typeBinding) {
|
|
@@ -568,11 +658,12 @@ export class DIFHandler {
|
|
|
568
658
|
* Caches the given reference value with the given address in the JS side cache.
|
|
569
659
|
* The reference must already be wrapped if necessary.
|
|
570
660
|
*/
|
|
571
|
-
cacheWrappedReferenceValue(address, originalValue, proxiedValue, observerId, metadata = {}) {
|
|
661
|
+
cacheWrappedReferenceValue(address, ownership, originalValue, proxiedValue, observerId, metadata = {}) {
|
|
572
662
|
const isProxifiedValue = this.isWeakKey(originalValue) &&
|
|
573
663
|
originalValue !== proxiedValue;
|
|
574
664
|
__classPrivateFieldGet(this, _DIFHandler_cache, "f").set(address, {
|
|
575
665
|
value: new WeakRef(proxiedValue),
|
|
666
|
+
maxOwnership: ownership,
|
|
576
667
|
originalValue: isProxifiedValue ? originalValue : null,
|
|
577
668
|
observerId,
|
|
578
669
|
});
|
|
@@ -598,20 +689,33 @@ export class DIFHandler {
|
|
|
598
689
|
__classPrivateFieldGet(this, _DIFHandler_observers, "f").delete(address);
|
|
599
690
|
// if observer is active, unregister it
|
|
600
691
|
if (observerId !== null) {
|
|
601
|
-
this.
|
|
692
|
+
this.unobserveSharedValueBindDirect(address, observerId);
|
|
602
693
|
}
|
|
603
694
|
});
|
|
604
695
|
finalizationRegistry.register(proxiedValue, address);
|
|
605
696
|
}
|
|
606
|
-
|
|
697
|
+
getCachedStateForSharedContainer(address, ownership) {
|
|
698
|
+
if (!__classPrivateFieldGet(this, _DIFHandler_cache, "f").has(address)) {
|
|
699
|
+
return "not_cached";
|
|
700
|
+
}
|
|
607
701
|
const cached = __classPrivateFieldGet(this, _DIFHandler_cache, "f").get(address);
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
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;
|
|
613
718
|
}
|
|
614
|
-
return undefined;
|
|
615
719
|
}
|
|
616
720
|
/**
|
|
617
721
|
* Creates a new reference containg the given JS value.
|
|
@@ -619,19 +723,24 @@ export class DIFHandler {
|
|
|
619
723
|
* but also propagates changes between JS and the DATEX runtime.
|
|
620
724
|
* If a reference for the given value already exists, an error is thrown.
|
|
621
725
|
*/
|
|
622
|
-
|
|
623
|
-
// if already bound to a reference, return the existing reference proxy (or the value itself)
|
|
726
|
+
createSharedValueFromJSValue(value, allowedType = null, mutability = SharedContainerMutability.Mutable) {
|
|
624
727
|
const pointerAddress = this.getPointerAddressForValue(value);
|
|
625
728
|
if (pointerAddress) {
|
|
626
729
|
throw new Error(`Value is already bound to a reference ($${pointerAddress}). Cannot create a new reference for the same value.`);
|
|
627
730
|
}
|
|
628
731
|
const difValue = this.convertJSValueToDIFValueContainer(value);
|
|
629
|
-
const ptrAddress = this.
|
|
732
|
+
const ptrAddress = this.constructSharedValue(difValue, mutability, allowedType);
|
|
630
733
|
// get inferred allowed type from pointer if not explicitly set
|
|
631
734
|
if (!allowedType) {
|
|
632
|
-
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;
|
|
633
743
|
}
|
|
634
|
-
return this.initReference(ptrAddress, value, mutability, allowedType);
|
|
635
744
|
}
|
|
636
745
|
isPrimitiveValue(value) {
|
|
637
746
|
return value === null || value === undefined ||
|
|
@@ -647,17 +756,17 @@ export class DIFHandler {
|
|
|
647
756
|
/**
|
|
648
757
|
* Wraps a given JS value in a Ref proxy if necessary.
|
|
649
758
|
*/
|
|
650
|
-
wrapJSValue(value, pointerAddress, _type = null) {
|
|
759
|
+
wrapJSValue(value, pointerAddress, mutability, _type = null) {
|
|
651
760
|
// primitive values are always wrapped in a Ref proxy
|
|
652
761
|
if (this.isWeakKey(value)) {
|
|
653
762
|
return value;
|
|
654
763
|
}
|
|
655
764
|
else {
|
|
656
|
-
return new
|
|
765
|
+
return new BaseSharedContainer(value, pointerAddress, mutability, this);
|
|
657
766
|
}
|
|
658
767
|
}
|
|
659
|
-
|
|
660
|
-
return value instanceof
|
|
768
|
+
isBaseSharedContainer(value) {
|
|
769
|
+
return value instanceof BaseSharedContainer;
|
|
661
770
|
}
|
|
662
771
|
wrapJSObjectInProxy(value) {
|
|
663
772
|
// deno-lint-ignore no-this-alias
|
|
@@ -665,14 +774,14 @@ export class DIFHandler {
|
|
|
665
774
|
return new Proxy(value, {
|
|
666
775
|
get(target, prop, receiver) {
|
|
667
776
|
const val = Reflect.get(target, prop, receiver);
|
|
668
|
-
if (val && typeof val === "object" && !self.
|
|
777
|
+
if (val && typeof val === "object" && !self.isBaseSharedContainer(val)) {
|
|
669
778
|
return self.wrapJSObjectInProxy(val);
|
|
670
779
|
}
|
|
671
780
|
return val;
|
|
672
781
|
},
|
|
673
782
|
set(target, prop, newValue, receiver) {
|
|
674
783
|
const oldValue = Reflect.get(target, prop, receiver);
|
|
675
|
-
if (!self.
|
|
784
|
+
if (!self.isBaseSharedContainer(oldValue)) {
|
|
676
785
|
throw new Error(`Cannot modify non-Ref property "${String(prop)}"`);
|
|
677
786
|
}
|
|
678
787
|
oldValue.value = newValue;
|
|
@@ -712,92 +821,96 @@ export class DIFHandler {
|
|
|
712
821
|
__classPrivateFieldGet(this, _DIFHandler_referenceMetadata, "f").get(__classPrivateFieldGet(this, _DIFHandler_proxyMapping, "f").get(value)?.deref()) ??
|
|
713
822
|
null);
|
|
714
823
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
}
|
|
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
|
+
// }
|
|
738
846
|
/**
|
|
739
847
|
* Converts a given JS value to its DIFValueContainer representation.
|
|
740
848
|
* This method can be called statically or with an instance to use the instance's DIFHandler context.
|
|
741
849
|
* NOTE: When called statically, there is no cache for already registered references, meaning that new references will be created
|
|
742
850
|
* for the same object each time this method is called.
|
|
743
851
|
*/
|
|
744
|
-
static convertJSValueToDIFValueContainer(value, difHandlerInstance) {
|
|
852
|
+
static convertJSValueToDIFValueContainer(value, difHandlerInstance, forceExplicitFormat = false) {
|
|
745
853
|
// if the value is a registered reference, return its address
|
|
746
854
|
const existingReference = difHandlerInstance &&
|
|
747
855
|
difHandlerInstance.tryGetReferenceMetadata(value);
|
|
748
856
|
if (existingReference) {
|
|
749
|
-
|
|
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) };
|
|
750
863
|
}
|
|
751
|
-
// assuming core values
|
|
752
864
|
// TODO: handle custom types
|
|
753
865
|
if (value === null) {
|
|
754
|
-
return
|
|
755
|
-
value: null,
|
|
756
|
-
};
|
|
866
|
+
return forceExplicitFormat ? [CoreLibTypeId.null, null] : null;
|
|
757
867
|
}
|
|
758
868
|
else if (value === undefined) {
|
|
759
|
-
return
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
CoreTypeAddress.null,
|
|
764
|
-
[JsLibTypeAddress.undefined],
|
|
765
|
-
],
|
|
766
|
-
},
|
|
767
|
-
value: null,
|
|
768
|
-
};
|
|
869
|
+
return JS_UNDEFINED;
|
|
870
|
+
}
|
|
871
|
+
else if (typeof value === "string") {
|
|
872
|
+
return forceExplicitFormat ? [CoreLibTypeId.text, value] : value;
|
|
769
873
|
}
|
|
770
874
|
else if (typeof value === "boolean") {
|
|
771
|
-
return
|
|
772
|
-
value,
|
|
773
|
-
};
|
|
875
|
+
return forceExplicitFormat ? [CoreLibTypeId.boolean, value] : value;
|
|
774
876
|
}
|
|
775
877
|
else if (typeof value === "number") {
|
|
776
|
-
return
|
|
777
|
-
value,
|
|
778
|
-
};
|
|
878
|
+
return forceExplicitFormat ? [CoreLibTypeId.decimal_f64, value] : value;
|
|
779
879
|
}
|
|
780
880
|
else if (typeof value === "bigint") {
|
|
781
|
-
return
|
|
782
|
-
type: CoreTypeAddress.integer_ibig,
|
|
783
|
-
value: value.toString(), // convert bigint to string for DIFValue
|
|
784
|
-
};
|
|
785
|
-
}
|
|
786
|
-
else if (typeof value === "string") {
|
|
787
|
-
return {
|
|
788
|
-
value,
|
|
789
|
-
};
|
|
881
|
+
return ibig(value);
|
|
790
882
|
}
|
|
791
883
|
else if (value instanceof Endpoint) {
|
|
792
|
-
return
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
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
|
+
}
|
|
905
|
+
}
|
|
906
|
+
else if (value instanceof Range) {
|
|
907
|
+
return [CoreLibTypeId.Range, [
|
|
908
|
+
this.convertJSValueToDIFValueContainer(value.start),
|
|
909
|
+
this.convertJSValueToDIFValueContainer(value.end),
|
|
910
|
+
]];
|
|
796
911
|
}
|
|
797
912
|
else if (Array.isArray(value)) {
|
|
798
|
-
return
|
|
799
|
-
value: value.map((v) => this.convertJSValueToDIFValueContainer(v)),
|
|
800
|
-
};
|
|
913
|
+
return [CoreLibTypeId.List, value.map((v) => this.convertJSValueToDIFValueContainer(v))];
|
|
801
914
|
}
|
|
802
915
|
else if (value instanceof Map) {
|
|
803
916
|
const map = value
|
|
@@ -805,19 +918,16 @@ export class DIFHandler {
|
|
|
805
918
|
this.convertJSValueToDIFValueContainer(k),
|
|
806
919
|
this.convertJSValueToDIFValueContainer(v),
|
|
807
920
|
]).toArray();
|
|
808
|
-
return {
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
};
|
|
921
|
+
return [CoreLibTypeId.Map, map, {
|
|
922
|
+
impl_type: [CoreLibTypeId.Map, [JsLibTypeAddress.map]],
|
|
923
|
+
}];
|
|
812
924
|
}
|
|
813
925
|
else if (typeof value === "object") {
|
|
814
926
|
const map = {};
|
|
815
927
|
for (const [key, val] of Object.entries(value)) {
|
|
816
928
|
map[key] = this.convertJSValueToDIFValueContainer(val);
|
|
817
929
|
}
|
|
818
|
-
return
|
|
819
|
-
value: map,
|
|
820
|
-
};
|
|
930
|
+
return [CoreLibTypeId.Map, map];
|
|
821
931
|
}
|
|
822
932
|
throw new Error("Unsupported type for conversion to DIFValue");
|
|
823
933
|
}
|
|
@@ -836,13 +946,7 @@ export class DIFHandler {
|
|
|
836
946
|
triggerSet(pointerAddress, key, value) {
|
|
837
947
|
const difKey = this.convertJSValueToDIFValueContainer(key);
|
|
838
948
|
const difValue = this.convertJSValueToDIFValueContainer(value);
|
|
839
|
-
|
|
840
|
-
kind: DIFUpdateKind.Set,
|
|
841
|
-
key: { kind: "value", value: difKey },
|
|
842
|
-
value: difValue,
|
|
843
|
-
};
|
|
844
|
-
console.log("Triggering set update", update);
|
|
845
|
-
this.updateReference(pointerAddress, update);
|
|
949
|
+
this.updateSharedValue(pointerAddress, setEntry(createDIFProperty(difKey, DIFPropertyKind.ValueContainer), difValue));
|
|
846
950
|
}
|
|
847
951
|
/**
|
|
848
952
|
* Triggers a 'set' update for the given pointer address, index and value.
|
|
@@ -852,73 +956,41 @@ export class DIFHandler {
|
|
|
852
956
|
throw new Error("Index must be a non-negative integer");
|
|
853
957
|
}
|
|
854
958
|
const difValue = this.convertJSValueToDIFValueContainer(value);
|
|
855
|
-
|
|
856
|
-
kind: DIFUpdateKind.Set,
|
|
857
|
-
key: { kind: "index", value: Number(index) },
|
|
858
|
-
value: difValue,
|
|
859
|
-
};
|
|
860
|
-
console.log("Triggering index set update", update);
|
|
861
|
-
this.updateReference(pointerAddress, update);
|
|
959
|
+
this.updateSharedValue(pointerAddress, setEntry(createDIFProperty(Number(index), DIFPropertyKind.Index), difValue));
|
|
862
960
|
}
|
|
863
961
|
/**
|
|
864
962
|
* Triggers an 'append' update for the given pointer address and value.
|
|
865
963
|
*/
|
|
866
964
|
triggerAppend(pointerAddress, value) {
|
|
867
965
|
const difValue = this.convertJSValueToDIFValueContainer(value);
|
|
868
|
-
|
|
869
|
-
kind: DIFUpdateKind.Append,
|
|
870
|
-
value: difValue,
|
|
871
|
-
};
|
|
872
|
-
console.log("Triggering append update", update);
|
|
873
|
-
this.updateReference(pointerAddress, update);
|
|
966
|
+
this.updateSharedValue(pointerAddress, appendEntry(difValue));
|
|
874
967
|
}
|
|
875
968
|
/**
|
|
876
969
|
* Triggers a 'replace' update for the given pointer address and key.
|
|
877
970
|
*/
|
|
878
971
|
triggerReplace(pointerAddress, value) {
|
|
879
972
|
const difValue = this.convertJSValueToDIFValueContainer(value);
|
|
880
|
-
|
|
881
|
-
kind: DIFUpdateKind.Replace,
|
|
882
|
-
value: difValue,
|
|
883
|
-
};
|
|
884
|
-
console.log("Triggering replace update", update);
|
|
885
|
-
this.updateReference(pointerAddress, update);
|
|
973
|
+
this.updateSharedValue(pointerAddress, replace(difValue));
|
|
886
974
|
}
|
|
887
975
|
/**
|
|
888
976
|
* Triggers a 'delete' update for the given pointer address and key.
|
|
889
977
|
*/
|
|
890
978
|
triggerDelete(pointerAddress, key) {
|
|
891
979
|
const difKey = this.convertJSValueToDIFValueContainer(key);
|
|
892
|
-
|
|
893
|
-
kind: DIFUpdateKind.Delete,
|
|
894
|
-
key: { kind: "value", value: difKey },
|
|
895
|
-
};
|
|
896
|
-
console.log("Triggering delete update", update);
|
|
897
|
-
this.updateReference(pointerAddress, update);
|
|
980
|
+
this.updateSharedValue(pointerAddress, deleteEntry(createDIFProperty(difKey, DIFPropertyKind.ValueContainer)));
|
|
898
981
|
}
|
|
899
982
|
/**
|
|
900
983
|
* Triggers a 'clear' update for the given pointer address.
|
|
901
984
|
*/
|
|
902
985
|
triggerClear(pointerAddress) {
|
|
903
|
-
|
|
904
|
-
kind: DIFUpdateKind.Clear,
|
|
905
|
-
};
|
|
906
|
-
console.log("Triggering clear update", update);
|
|
907
|
-
this.updateReference(pointerAddress, update);
|
|
986
|
+
this.updateSharedValue(pointerAddress, clear());
|
|
908
987
|
}
|
|
909
988
|
/**
|
|
910
989
|
* Triggers a 'list splice' update for the given pointer address.
|
|
911
990
|
*/
|
|
912
991
|
triggerListSplice(pointerAddress, start, deleteCount, items) {
|
|
913
992
|
const difItems = items.map((item) => this.convertJSValueToDIFValueContainer(item));
|
|
914
|
-
|
|
915
|
-
kind: DIFUpdateKind.ListSplice,
|
|
916
|
-
start,
|
|
917
|
-
delete_count: deleteCount,
|
|
918
|
-
items: difItems,
|
|
919
|
-
};
|
|
920
|
-
console.log("Triggering list splice update", update);
|
|
921
|
-
this.updateReference(pointerAddress, update);
|
|
993
|
+
this.updateSharedValue(pointerAddress, listSplice(start, deleteCount, difItems));
|
|
922
994
|
}
|
|
923
995
|
}
|
|
924
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();
|