@neocompose/cli 0.73.2 → 0.75.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/test-worker.mjs
CHANGED
|
@@ -1124,16 +1124,16 @@ function memberKindSupportsDistribution(kind) {
|
|
|
1124
1124
|
return memberKindSupportsStorage(kind);
|
|
1125
1125
|
}
|
|
1126
1126
|
|
|
1127
|
-
// node_modules/uuid/dist-node/regex.js
|
|
1127
|
+
// ../node_modules/uuid/dist-node/regex.js
|
|
1128
1128
|
var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
|
|
1129
1129
|
|
|
1130
|
-
// node_modules/uuid/dist-node/validate.js
|
|
1130
|
+
// ../node_modules/uuid/dist-node/validate.js
|
|
1131
1131
|
function validate(uuid) {
|
|
1132
1132
|
return typeof uuid === "string" && regex_default.test(uuid);
|
|
1133
1133
|
}
|
|
1134
1134
|
var validate_default = validate;
|
|
1135
1135
|
|
|
1136
|
-
// node_modules/uuid/dist-node/parse.js
|
|
1136
|
+
// ../node_modules/uuid/dist-node/parse.js
|
|
1137
1137
|
function parse(uuid) {
|
|
1138
1138
|
if (!validate_default(uuid)) {
|
|
1139
1139
|
throw TypeError("Invalid UUID");
|
|
@@ -1143,7 +1143,7 @@ function parse(uuid) {
|
|
|
1143
1143
|
}
|
|
1144
1144
|
var parse_default = parse;
|
|
1145
1145
|
|
|
1146
|
-
// node_modules/uuid/dist-node/stringify.js
|
|
1146
|
+
// ../node_modules/uuid/dist-node/stringify.js
|
|
1147
1147
|
var byteToHex = [];
|
|
1148
1148
|
for (let i = 0; i < 256; ++i) {
|
|
1149
1149
|
byteToHex.push((i + 256).toString(16).slice(1));
|
|
@@ -1152,13 +1152,13 @@ function unsafeStringify(arr, offset = 0) {
|
|
|
1152
1152
|
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
1153
1153
|
}
|
|
1154
1154
|
|
|
1155
|
-
// node_modules/uuid/dist-node/rng.js
|
|
1155
|
+
// ../node_modules/uuid/dist-node/rng.js
|
|
1156
1156
|
var rnds8 = new Uint8Array(16);
|
|
1157
1157
|
function rng() {
|
|
1158
1158
|
return crypto.getRandomValues(rnds8);
|
|
1159
1159
|
}
|
|
1160
1160
|
|
|
1161
|
-
// node_modules/uuid/dist-node/v35.js
|
|
1161
|
+
// ../node_modules/uuid/dist-node/v35.js
|
|
1162
1162
|
function stringToBytes(str) {
|
|
1163
1163
|
str = unescape(encodeURIComponent(str));
|
|
1164
1164
|
const bytes = new Uint8Array(str.length);
|
|
@@ -1197,7 +1197,7 @@ function v35(version, hash, value, namespace, buf, offset) {
|
|
|
1197
1197
|
return unsafeStringify(bytes);
|
|
1198
1198
|
}
|
|
1199
1199
|
|
|
1200
|
-
// node_modules/uuid/dist-node/v4.js
|
|
1200
|
+
// ../node_modules/uuid/dist-node/v4.js
|
|
1201
1201
|
function v4(options, buf, offset) {
|
|
1202
1202
|
if (!buf && !options && crypto.randomUUID) {
|
|
1203
1203
|
return crypto.randomUUID();
|
|
@@ -1226,7 +1226,7 @@ function _v4(options, buf, offset) {
|
|
|
1226
1226
|
}
|
|
1227
1227
|
var v4_default = v4;
|
|
1228
1228
|
|
|
1229
|
-
// node_modules/uuid/dist-node/sha1.js
|
|
1229
|
+
// ../node_modules/uuid/dist-node/sha1.js
|
|
1230
1230
|
import { createHash } from "node:crypto";
|
|
1231
1231
|
function sha1(bytes) {
|
|
1232
1232
|
if (Array.isArray(bytes)) {
|
|
@@ -1238,7 +1238,7 @@ function sha1(bytes) {
|
|
|
1238
1238
|
}
|
|
1239
1239
|
var sha1_default = sha1;
|
|
1240
1240
|
|
|
1241
|
-
// node_modules/uuid/dist-node/v5.js
|
|
1241
|
+
// ../node_modules/uuid/dist-node/v5.js
|
|
1242
1242
|
function v5(value, namespace, buf, offset) {
|
|
1243
1243
|
return v35(80, sha1_default, value, namespace, buf, offset);
|
|
1244
1244
|
}
|
|
@@ -3629,24 +3629,30 @@ function isNSInstructionTry(value) {
|
|
|
3629
3629
|
}
|
|
3630
3630
|
return true;
|
|
3631
3631
|
}
|
|
3632
|
-
function
|
|
3633
|
-
const
|
|
3634
|
-
if (instruction?.type !== "addChangeListener" /* addChangeListener */ && instruction?.type !== "removeChangeListener" /* removeChangeListener */)
|
|
3635
|
-
return false;
|
|
3636
|
-
const target = instruction.target;
|
|
3632
|
+
function isNSChangeListenerTarget(value) {
|
|
3633
|
+
const target = value;
|
|
3637
3634
|
if (!target || typeof target.memberId !== "string" || target.memberId.length === 0)
|
|
3638
3635
|
return false;
|
|
3639
3636
|
if (!isNSPointer(target.owner) || !isNSTypeInfo(target.typeInfo))
|
|
3640
3637
|
return false;
|
|
3641
|
-
|
|
3642
|
-
|
|
3638
|
+
return target.writability !== void 0 && Object.values(NSWritability).includes(target.writability);
|
|
3639
|
+
}
|
|
3640
|
+
function isNSInstructionChangeListener(value) {
|
|
3641
|
+
const instruction = value;
|
|
3642
|
+
if (instruction?.type !== "addChangeListener" /* addChangeListener */ && instruction?.type !== "removeChangeListener" /* removeChangeListener */)
|
|
3643
|
+
return false;
|
|
3644
|
+
return isNSChangeListenerTarget(instruction.target) && isNSPointer(instruction.listener);
|
|
3645
|
+
}
|
|
3646
|
+
function isNSInstructionClearChangeListeners(value) {
|
|
3647
|
+
const instruction = value;
|
|
3648
|
+
return instruction?.type === "clearChangeListeners" /* clearChangeListeners */ && isNSChangeListenerTarget(instruction.target);
|
|
3643
3649
|
}
|
|
3644
3650
|
function isNSInstructionDebug(value) {
|
|
3645
3651
|
const v = value;
|
|
3646
3652
|
return v?.type === "debug" /* debug */ && ["log", "warning", "error", "assert"].includes(v.severity ?? "") && isNSPointer(v.message) && isNSTypeInfo(v.messageType) && (v.severity === "assert" ? isNSPointer(v.condition) : v.condition === void 0);
|
|
3647
3653
|
}
|
|
3648
3654
|
function isNSInstruction(value) {
|
|
3649
|
-
return isNSInstructionDebug(value) || isNSInstructionVariable(value) || isNSInstructionIfBranch(value) || isNSInstructionReturn(value) || isNSInstructionThrow(value) || isNSInstructionAssign(value) || isNSInstructionCollectionCall(value) || isNSInstructionFunctionCall(value) || isNSInstructionConditionLoop(value) || isNSInstructionFor(value) || isNSInstructionForEach(value) || isNSInstructionBreak(value) || isNSInstructionContinue(value) || isNSInstructionSwitch(value) || isNSInstructionTry(value) || isNSInstructionChangeListener(value) || isNSInstructionAddActionListener(value) || isNSInstructionRemoveActionListener(value);
|
|
3655
|
+
return isNSInstructionDebug(value) || isNSInstructionVariable(value) || isNSInstructionIfBranch(value) || isNSInstructionReturn(value) || isNSInstructionThrow(value) || isNSInstructionAssign(value) || isNSInstructionCollectionCall(value) || isNSInstructionFunctionCall(value) || isNSInstructionConditionLoop(value) || isNSInstructionFor(value) || isNSInstructionForEach(value) || isNSInstructionBreak(value) || isNSInstructionContinue(value) || isNSInstructionSwitch(value) || isNSInstructionTry(value) || isNSInstructionChangeListener(value) || isNSInstructionClearChangeListeners(value) || isNSInstructionAddActionListener(value) || isNSInstructionRemoveActionListener(value);
|
|
3650
3656
|
}
|
|
3651
3657
|
function isNSInstructions(value) {
|
|
3652
3658
|
return Array.isArray(value) && value.every(isNSInstruction);
|
|
@@ -13204,6 +13210,9 @@ function listenerWritesByOwner(state) {
|
|
|
13204
13210
|
}
|
|
13205
13211
|
return index.owners;
|
|
13206
13212
|
}
|
|
13213
|
+
function changeListenerWriteEdit(write) {
|
|
13214
|
+
return write.operation === "clear" ? { kind: "replace", targets: [] } : { kind: write.operation, target: write.listener };
|
|
13215
|
+
}
|
|
13207
13216
|
|
|
13208
13217
|
// ../src/runtime/neoscript/typed-aggregate-row-references.ts
|
|
13209
13218
|
function visitTypedAggregateRowReferences(value, rawType, visitor) {
|
|
@@ -14859,6 +14868,144 @@ function checkedCoordinate(value) {
|
|
|
14859
14868
|
return value;
|
|
14860
14869
|
}
|
|
14861
14870
|
|
|
14871
|
+
// ../src/runtime/neoscript/getter-subscriptions.ts
|
|
14872
|
+
var NeoScriptGetterSubscription = class {
|
|
14873
|
+
constructor(rowId, getterId, classId) {
|
|
14874
|
+
this.rowId = rowId;
|
|
14875
|
+
this.getterId = getterId;
|
|
14876
|
+
this.classId = classId;
|
|
14877
|
+
}
|
|
14878
|
+
rowId;
|
|
14879
|
+
getterId;
|
|
14880
|
+
classId;
|
|
14881
|
+
targets = [];
|
|
14882
|
+
reads = new InitializerReadSet();
|
|
14883
|
+
queued = false;
|
|
14884
|
+
/** Queued only to arm: its first read calls no handler. */
|
|
14885
|
+
arming = true;
|
|
14886
|
+
/** Its handlers are running. */
|
|
14887
|
+
handling = false;
|
|
14888
|
+
};
|
|
14889
|
+
var NO_SUBSCRIPTIONS = [];
|
|
14890
|
+
var staticReadKey = (memberId) => `static:${memberId}`;
|
|
14891
|
+
function* readKeys(reads) {
|
|
14892
|
+
yield* reads.valueIds;
|
|
14893
|
+
yield* reads.containerIds;
|
|
14894
|
+
yield* reads.containerEntryReadIds;
|
|
14895
|
+
for (const id of reads.staticMemberIds) yield staticReadKey(id);
|
|
14896
|
+
}
|
|
14897
|
+
var NeoScriptGetterSubscriptions = class _NeoScriptGetterSubscriptions {
|
|
14898
|
+
byRow = /* @__PURE__ */ new Map();
|
|
14899
|
+
byRead = /* @__PURE__ */ new Map();
|
|
14900
|
+
/** Reads no row id names, such as corpus or world queries, hear every write. */
|
|
14901
|
+
readingEverything = /* @__PURE__ */ new Set();
|
|
14902
|
+
pending = [];
|
|
14903
|
+
get empty() {
|
|
14904
|
+
return this.byRow.size === 0;
|
|
14905
|
+
}
|
|
14906
|
+
get(rowId, getterId) {
|
|
14907
|
+
return this.byRow.get(rowId)?.get(getterId);
|
|
14908
|
+
}
|
|
14909
|
+
add(subscription) {
|
|
14910
|
+
this.register(subscription);
|
|
14911
|
+
this.queue(subscription);
|
|
14912
|
+
}
|
|
14913
|
+
drop(subscription) {
|
|
14914
|
+
const getters = this.byRow.get(subscription.rowId);
|
|
14915
|
+
if (getters?.get(subscription.getterId) !== subscription) return;
|
|
14916
|
+
getters.delete(subscription.getterId);
|
|
14917
|
+
if (getters.size === 0) this.byRow.delete(subscription.rowId);
|
|
14918
|
+
this.unindex(subscription);
|
|
14919
|
+
}
|
|
14920
|
+
noteValueWrite(rowId) {
|
|
14921
|
+
this.noteRead(rowId);
|
|
14922
|
+
}
|
|
14923
|
+
noteStaticBinding(memberId) {
|
|
14924
|
+
this.noteRead(staticReadKey(memberId));
|
|
14925
|
+
}
|
|
14926
|
+
/** Replace what the subscription's last read touched. */
|
|
14927
|
+
setReads(subscription, reads) {
|
|
14928
|
+
this.unindex(subscription);
|
|
14929
|
+
subscription.reads = reads;
|
|
14930
|
+
if (this.get(subscription.rowId, subscription.getterId) !== subscription)
|
|
14931
|
+
return;
|
|
14932
|
+
if (reads.corpusReadReasons.size > 0 || reads.worldQueries.size > 0)
|
|
14933
|
+
this.readingEverything.add(subscription);
|
|
14934
|
+
for (const key of readKeys(reads)) {
|
|
14935
|
+
let subscriptions = this.byRead.get(key);
|
|
14936
|
+
if (subscriptions === void 0) {
|
|
14937
|
+
subscriptions = /* @__PURE__ */ new Set();
|
|
14938
|
+
this.byRead.set(key, subscriptions);
|
|
14939
|
+
}
|
|
14940
|
+
subscriptions.add(subscription);
|
|
14941
|
+
}
|
|
14942
|
+
}
|
|
14943
|
+
takePending() {
|
|
14944
|
+
if (this.pending.length === 0) return NO_SUBSCRIPTIONS;
|
|
14945
|
+
const pending = this.pending;
|
|
14946
|
+
this.pending = [];
|
|
14947
|
+
return pending;
|
|
14948
|
+
}
|
|
14949
|
+
/** A throw skipped `drained` from `next` on. They stay queued, so none goes deaf. */
|
|
14950
|
+
requeue(drained, next) {
|
|
14951
|
+
for (let index = next; index < drained.length; index += 1)
|
|
14952
|
+
this.pending.push(drained[index]);
|
|
14953
|
+
}
|
|
14954
|
+
/** A copy for a fresh runtime over the same rows, armed exactly as these are. */
|
|
14955
|
+
clone() {
|
|
14956
|
+
const cloned = new _NeoScriptGetterSubscriptions();
|
|
14957
|
+
const copies = /* @__PURE__ */ new Map();
|
|
14958
|
+
for (const getters of this.byRow.values()) {
|
|
14959
|
+
for (const source of getters.values()) {
|
|
14960
|
+
const copy = new NeoScriptGetterSubscription(
|
|
14961
|
+
source.rowId,
|
|
14962
|
+
source.getterId,
|
|
14963
|
+
source.classId
|
|
14964
|
+
);
|
|
14965
|
+
copy.targets.push(...source.targets);
|
|
14966
|
+
copy.arming = source.arming;
|
|
14967
|
+
copies.set(source, copy);
|
|
14968
|
+
cloned.register(copy);
|
|
14969
|
+
cloned.setReads(copy, source.reads);
|
|
14970
|
+
}
|
|
14971
|
+
}
|
|
14972
|
+
for (const source of this.pending) {
|
|
14973
|
+
const copy = copies.get(source);
|
|
14974
|
+
if (copy !== void 0) cloned.queue(copy);
|
|
14975
|
+
}
|
|
14976
|
+
return cloned;
|
|
14977
|
+
}
|
|
14978
|
+
register(subscription) {
|
|
14979
|
+
let getters = this.byRow.get(subscription.rowId);
|
|
14980
|
+
if (getters === void 0) {
|
|
14981
|
+
getters = /* @__PURE__ */ new Map();
|
|
14982
|
+
this.byRow.set(subscription.rowId, getters);
|
|
14983
|
+
}
|
|
14984
|
+
getters.set(subscription.getterId, subscription);
|
|
14985
|
+
}
|
|
14986
|
+
queue(subscription) {
|
|
14987
|
+
if (subscription.queued) return;
|
|
14988
|
+
subscription.queued = true;
|
|
14989
|
+
this.pending.push(subscription);
|
|
14990
|
+
}
|
|
14991
|
+
noteRead(key) {
|
|
14992
|
+
const subscriptions = this.byRead.get(key);
|
|
14993
|
+
if (subscriptions !== void 0)
|
|
14994
|
+
for (const subscription of subscriptions) this.queue(subscription);
|
|
14995
|
+
for (const subscription of this.readingEverything)
|
|
14996
|
+
if (!subscription.handling) this.queue(subscription);
|
|
14997
|
+
}
|
|
14998
|
+
unindex(subscription) {
|
|
14999
|
+
this.readingEverything.delete(subscription);
|
|
15000
|
+
for (const key of readKeys(subscription.reads)) {
|
|
15001
|
+
const subscriptions = this.byRead.get(key);
|
|
15002
|
+
if (subscriptions === void 0) continue;
|
|
15003
|
+
subscriptions.delete(subscription);
|
|
15004
|
+
if (subscriptions.size === 0) this.byRead.delete(key);
|
|
15005
|
+
}
|
|
15006
|
+
}
|
|
15007
|
+
};
|
|
15008
|
+
|
|
14862
15009
|
// ../src/models/decimal/decimal-math.ts
|
|
14863
15010
|
var DecimalOverflowError = class extends Error {
|
|
14864
15011
|
};
|
|
@@ -15446,6 +15593,7 @@ function evalMemberById(vm, id) {
|
|
|
15446
15593
|
return vm.members.find((a) => a.id === id) ?? null;
|
|
15447
15594
|
}
|
|
15448
15595
|
function evalValueById(ctx, id, runtimeValues, overlayValues) {
|
|
15596
|
+
ctx.__getterReads?.add(id);
|
|
15449
15597
|
if (ctx.__removedValueIds?.has(id)) {
|
|
15450
15598
|
ctx.valueDependencies?.add(id);
|
|
15451
15599
|
return null;
|
|
@@ -16120,8 +16268,13 @@ function bindThisValue(ctx, thisValue) {
|
|
|
16120
16268
|
const rowId = thisValue === ctx.thisValue ? ctx.thisValueRowId : trackedRowForValueReference(thisValue, ctx)?.id;
|
|
16121
16269
|
return { ...ctx, thisValue, thisValueRowId: rowId };
|
|
16122
16270
|
}
|
|
16271
|
+
function observeValueWrite(ctx, row) {
|
|
16272
|
+
ctx.beforeValueWrite?.(row);
|
|
16273
|
+
ctx.__getterSubscriptions?.noteValueWrite(row.id);
|
|
16274
|
+
}
|
|
16123
16275
|
function assertStoredReplayMutableValue(value, ctx, label, key) {
|
|
16124
|
-
|
|
16276
|
+
const observesWrites = ctx.beforeValueWrite !== void 0 || ctx.__getterSubscriptions?.empty === false;
|
|
16277
|
+
if (ctx.storedConstructionReplay !== true && !ctx.assertValueWritable && !observesWrites)
|
|
16125
16278
|
return;
|
|
16126
16279
|
let rowId = findKnownRowIdByValueReference(value, ctx);
|
|
16127
16280
|
if (rowId === null) return;
|
|
@@ -16140,7 +16293,7 @@ function assertStoredReplayMutableValue(value, ctx, label, key) {
|
|
|
16140
16293
|
);
|
|
16141
16294
|
if (ctx.__runtimeSessionValues?.has(rowId) !== true)
|
|
16142
16295
|
ctx.assertValueWritable?.(rowId);
|
|
16143
|
-
if (row) ctx
|
|
16296
|
+
if (row) observeValueWrite(ctx, row);
|
|
16144
16297
|
if (ctx.__runtimeSessionValues?.has(rowId) === true) return;
|
|
16145
16298
|
if (ctx.storedConstructionReplay !== true) return;
|
|
16146
16299
|
throw new NSGetterRuntimeError(
|
|
@@ -16649,10 +16802,14 @@ function readNeoScriptRuntimeRow(ctx, valueId) {
|
|
|
16649
16802
|
ctx.__valueOverlay
|
|
16650
16803
|
);
|
|
16651
16804
|
}
|
|
16805
|
+
function getterSubscriptionsFor(ctx) {
|
|
16806
|
+
return ctx.getterDispatch === "afterEntryStatement" /* AfterEntryStatement */ ? new NeoScriptGetterSubscriptions() : void 0;
|
|
16807
|
+
}
|
|
16652
16808
|
function withEvaluationRuntime(ctx, writes) {
|
|
16653
16809
|
if (ctx.__runtimeSessionValues !== void 0 && ctx.__executionState !== void 0 && ctx.__valueOverlay !== void 0) {
|
|
16654
16810
|
ctx.__unorderedListProjections ??= createUnorderedListProjectionCache();
|
|
16655
16811
|
ctx.__runtimeClassOverrides ??= /* @__PURE__ */ new Map();
|
|
16812
|
+
ctx.__getterSubscriptions ??= getterSubscriptionsFor(ctx);
|
|
16656
16813
|
return ctx;
|
|
16657
16814
|
}
|
|
16658
16815
|
const overlay = ctx.__valueOverlay ?? (ctx.storedConstructionReplay === true ? /* @__PURE__ */ new Map() : buildValueOverlay(ctx.vm));
|
|
@@ -16677,6 +16834,7 @@ function withEvaluationRuntime(ctx, writes) {
|
|
|
16677
16834
|
trigger: remap(ctx.dialogueContext.trigger)
|
|
16678
16835
|
},
|
|
16679
16836
|
__runtimeSessionValues: runtimeSessionValues,
|
|
16837
|
+
__getterSubscriptions: ctx.__getterSubscriptions ?? getterSubscriptionsFor(ctx),
|
|
16680
16838
|
__copiedChangeListeners: ctx.__copiedChangeListeners ?? /* @__PURE__ */ new Map(),
|
|
16681
16839
|
__runtimeClassOverrides: ctx.__runtimeClassOverrides ?? /* @__PURE__ */ new Map(),
|
|
16682
16840
|
__saveStaticBindings: ctx.__saveStaticBindings ?? staticBindingMap(ctx.saveStaticBindings),
|
|
@@ -16883,33 +17041,41 @@ function finalizeConstructorAllocations(ctx, returnValue, ownsInvocationState, r
|
|
|
16883
17041
|
const listenerEdges = /* @__PURE__ */ new Map();
|
|
16884
17042
|
for (const write of state.writes) {
|
|
16885
17043
|
if (!retainListenerReceivers || write.kind !== "changeListener") continue;
|
|
17044
|
+
const slotKey = JSON.stringify([write.ownerId, write.memberId]);
|
|
17045
|
+
if (write.operation === "clear") {
|
|
17046
|
+
listenerEdges.delete(slotKey);
|
|
17047
|
+
continue;
|
|
17048
|
+
}
|
|
16886
17049
|
const key = JSON.stringify([
|
|
16887
|
-
write.ownerId,
|
|
16888
|
-
write.memberId,
|
|
16889
17050
|
write.listener.memberId,
|
|
16890
17051
|
write.listener.valueId
|
|
16891
17052
|
]);
|
|
16892
|
-
|
|
16893
|
-
|
|
17053
|
+
let edges = listenerEdges.get(slotKey);
|
|
17054
|
+
if (write.operation === "remove") edges?.delete(key);
|
|
17055
|
+
else {
|
|
17056
|
+
if (edges === void 0) listenerEdges.set(slotKey, edges = /* @__PURE__ */ new Map());
|
|
17057
|
+
edges.set(key, write);
|
|
17058
|
+
}
|
|
16894
17059
|
}
|
|
16895
17060
|
const externalListenerReceivers = /* @__PURE__ */ new Set();
|
|
16896
|
-
for (const
|
|
16897
|
-
|
|
16898
|
-
|
|
16899
|
-
|
|
16900
|
-
|
|
16901
|
-
|
|
16902
|
-
if (
|
|
16903
|
-
|
|
16904
|
-
|
|
16905
|
-
|
|
16906
|
-
|
|
16907
|
-
dependencies
|
|
16908
|
-
|
|
17061
|
+
for (const edges of listenerEdges.values())
|
|
17062
|
+
for (const write of edges.values()) {
|
|
17063
|
+
if (write.listener.valueId === null) continue;
|
|
17064
|
+
const receiverGroup = groupByRowId.get(write.listener.valueId);
|
|
17065
|
+
if (receiverGroup === void 0) continue;
|
|
17066
|
+
const ownerGroup = groupByRowId.get(write.ownerId);
|
|
17067
|
+
if (ownerGroup === void 0) {
|
|
17068
|
+
if (rowForCleanup(write.ownerId) !== null)
|
|
17069
|
+
externalListenerReceivers.add(receiverGroup);
|
|
17070
|
+
} else {
|
|
17071
|
+
let dependencies = state.constructorGroupDependencies.get(ownerGroup);
|
|
17072
|
+
if (dependencies === void 0) {
|
|
17073
|
+
dependencies = /* @__PURE__ */ new Set();
|
|
17074
|
+
state.constructorGroupDependencies.set(ownerGroup, dependencies);
|
|
17075
|
+
}
|
|
17076
|
+
dependencies.add(receiverGroup);
|
|
16909
17077
|
}
|
|
16910
|
-
dependencies.add(receiverGroup);
|
|
16911
17078
|
}
|
|
16912
|
-
}
|
|
16913
17079
|
const markConstructorGroupEscaped = (rootId) => {
|
|
16914
17080
|
if (escapedRoots.has(rootId)) return;
|
|
16915
17081
|
escapedRoots.add(rootId);
|
|
@@ -17106,7 +17272,7 @@ function finalizeConstructorAllocations(ctx, returnValue, ownsInvocationState, r
|
|
|
17106
17272
|
const survivingWrites = state.writes.filter((write) => {
|
|
17107
17273
|
if (write.kind === "changeListener") {
|
|
17108
17274
|
if (collectedIds.has(write.ownerId)) return false;
|
|
17109
|
-
return write.listener.valueId === null || !collectedIds.has(write.listener.valueId);
|
|
17275
|
+
return write.operation === "clear" || write.listener.valueId === null || !collectedIds.has(write.listener.valueId);
|
|
17110
17276
|
}
|
|
17111
17277
|
const destination = write.resolvedDestination;
|
|
17112
17278
|
const destinationId = destination !== void 0 && "containerValueId" in destination ? destination.containerValueId : void 0;
|
|
@@ -17680,6 +17846,7 @@ function validateTryInstruction(instruction) {
|
|
|
17680
17846
|
function evalBody(body, scope, ctx, options, preparedFrame) {
|
|
17681
17847
|
const state = ctx.__executionState;
|
|
17682
17848
|
if (!state) return evalInstructions(body.instructions, scope, ctx, options);
|
|
17849
|
+
const hostBody = state.frames.length === 0 && ctx.__getterSubscriptions !== void 0;
|
|
17683
17850
|
state.frames.push(
|
|
17684
17851
|
preparedFrame ?? {
|
|
17685
17852
|
name: body.source?.name ?? "<body>",
|
|
@@ -17688,7 +17855,14 @@ function evalBody(body, scope, ctx, options, preparedFrame) {
|
|
|
17688
17855
|
}
|
|
17689
17856
|
);
|
|
17690
17857
|
try {
|
|
17691
|
-
|
|
17858
|
+
if (!hostBody)
|
|
17859
|
+
return evalInstructions(body.instructions, scope, ctx, options);
|
|
17860
|
+
const result = evalInstructions(body.instructions, scope, ctx, {
|
|
17861
|
+
...options,
|
|
17862
|
+
dispatchesGetterChanges: true
|
|
17863
|
+
});
|
|
17864
|
+
dispatchGetterSubscriptions(ctx);
|
|
17865
|
+
return result;
|
|
17692
17866
|
} catch (error) {
|
|
17693
17867
|
attachNeoScriptTrace(error, state);
|
|
17694
17868
|
throw error;
|
|
@@ -17852,7 +18026,8 @@ function evalInstructions(instructions, scope, ctx, options) {
|
|
|
17852
18026
|
break;
|
|
17853
18027
|
}
|
|
17854
18028
|
case "addChangeListener" /* addChangeListener */:
|
|
17855
|
-
case "removeChangeListener" /* removeChangeListener */:
|
|
18029
|
+
case "removeChangeListener" /* removeChangeListener */:
|
|
18030
|
+
case "clearChangeListeners" /* clearChangeListeners */: {
|
|
17856
18031
|
evalChangeListenerInstruction(ins, scope, ctx, options);
|
|
17857
18032
|
break;
|
|
17858
18033
|
}
|
|
@@ -18067,6 +18242,8 @@ function evalInstructions(instructions, scope, ctx, options) {
|
|
|
18067
18242
|
return { kind: "continue" };
|
|
18068
18243
|
}
|
|
18069
18244
|
void touchUnknown(ins);
|
|
18245
|
+
if (options.dispatchesGetterChanges === true)
|
|
18246
|
+
dispatchGetterSubscriptions(ctx);
|
|
18070
18247
|
} catch (error) {
|
|
18071
18248
|
positionNeoScriptFrame(ctx, ins.source);
|
|
18072
18249
|
if (ctx.__executionState)
|
|
@@ -18141,6 +18318,30 @@ function resolveNeoScriptChangeListenerSlot(ownerId, memberId, ctx) {
|
|
|
18141
18318
|
typeInfo: changeListenerObservedType(raw, member, env, ctx)
|
|
18142
18319
|
};
|
|
18143
18320
|
}
|
|
18321
|
+
function resolveNeoScriptGetterListenerSlot(ownerId, memberId, ctx) {
|
|
18322
|
+
const owner = evalValueById(
|
|
18323
|
+
ctx,
|
|
18324
|
+
ownerId,
|
|
18325
|
+
ctx.__runtimeSessionValues,
|
|
18326
|
+
ctx.__valueOverlay
|
|
18327
|
+
);
|
|
18328
|
+
if (owner === null || owner.value === null) return null;
|
|
18329
|
+
const entry = changeListenerMemberOnOwner(owner, memberId, ctx);
|
|
18330
|
+
if (entry === void 0) return null;
|
|
18331
|
+
const member = evalMemberById(ctx.vm, entry.memberId);
|
|
18332
|
+
if (member === null || !isMemberNSProperty(member)) return null;
|
|
18333
|
+
if (isStaticMember(member)) return null;
|
|
18334
|
+
const env = runtimeGenericEnvForValueRow(owner, ctx, /* @__PURE__ */ new Set());
|
|
18335
|
+
const typeInfo = substituteRuntimeTypeInfo(member.returnTypeInfo, env, ctx);
|
|
18336
|
+
if (typeInfo.type === NS_TYPE_VOID) return null;
|
|
18337
|
+
return {
|
|
18338
|
+
owner,
|
|
18339
|
+
member,
|
|
18340
|
+
memberId: evaluatorResolutionCache(ctx).canonicalMemberId(member.id),
|
|
18341
|
+
schemaKey: entry.schemaKey,
|
|
18342
|
+
typeInfo
|
|
18343
|
+
};
|
|
18344
|
+
}
|
|
18144
18345
|
function changeListenerObservedType(raw, member, env, ctx) {
|
|
18145
18346
|
const runtime = runtimeTypeInfoForMember(raw, env, ctx, /* @__PURE__ */ new Set());
|
|
18146
18347
|
if (!isMemberLookup(member)) return runtime;
|
|
@@ -18163,6 +18364,18 @@ function changeListenerObservedType(raw, member, env, ctx) {
|
|
|
18163
18364
|
required: isRequiredMember(member)
|
|
18164
18365
|
};
|
|
18165
18366
|
}
|
|
18367
|
+
function readNeoScriptChangeListenerValue(slot, ctx) {
|
|
18368
|
+
const result = dispatchSchemaMember(
|
|
18369
|
+
readRowValue(slot.owner, ctx),
|
|
18370
|
+
slot.schemaKey,
|
|
18371
|
+
ctx
|
|
18372
|
+
);
|
|
18373
|
+
if (result.kind !== "ok")
|
|
18374
|
+
throw new NSGetterRuntimeError(
|
|
18375
|
+
`OnChanged cannot read '${slot.owner.id}/${slot.memberId}'.`
|
|
18376
|
+
);
|
|
18377
|
+
return result.value;
|
|
18378
|
+
}
|
|
18166
18379
|
function resolveNeoScriptChangeListenerHandler(slot, target, ctx) {
|
|
18167
18380
|
const raw = evalMemberById(ctx.vm, target.memberId);
|
|
18168
18381
|
if (raw === null) return null;
|
|
@@ -18224,15 +18437,29 @@ function evalChangeListenerInstruction(ins, scope, ctx, options) {
|
|
|
18224
18437
|
throw new NSGetterRuntimeError(
|
|
18225
18438
|
"OnChanged requires an existing logical owner."
|
|
18226
18439
|
);
|
|
18227
|
-
const
|
|
18440
|
+
const stored = resolveNeoScriptChangeListenerSlot(
|
|
18228
18441
|
owner.id,
|
|
18229
18442
|
ins.target.memberId,
|
|
18230
18443
|
ctx
|
|
18231
18444
|
);
|
|
18445
|
+
const getter = stored === null ? resolveNeoScriptGetterListenerSlot(owner.id, ins.target.memberId, ctx) : null;
|
|
18446
|
+
const slot = stored ?? getter;
|
|
18232
18447
|
if (slot === null)
|
|
18233
18448
|
throw new NSGetterRuntimeError(
|
|
18234
|
-
`OnChanged member '${ins.target.memberId}' is not an observable
|
|
18449
|
+
`OnChanged member '${ins.target.memberId}' is not an observable member or getter of owner '${owner.id}'.`
|
|
18235
18450
|
);
|
|
18451
|
+
if (ins.type === "clearChangeListeners" /* clearChangeListeners */) {
|
|
18452
|
+
if (getter !== null) clearGetterSubscription(getter, ctx);
|
|
18453
|
+
else
|
|
18454
|
+
options.writes.push({
|
|
18455
|
+
kind: "changeListener",
|
|
18456
|
+
target: ins.target,
|
|
18457
|
+
ownerId: owner.id,
|
|
18458
|
+
memberId: slot.memberId,
|
|
18459
|
+
operation: "clear"
|
|
18460
|
+
});
|
|
18461
|
+
return;
|
|
18462
|
+
}
|
|
18236
18463
|
const listener = evalPointer(ins.listener, scope, ctx);
|
|
18237
18464
|
if (!isMemberDelegateTarget(listener))
|
|
18238
18465
|
throw new NSGetterRuntimeError(
|
|
@@ -18243,6 +18470,15 @@ function evalChangeListenerInstruction(ins, scope, ctx, options) {
|
|
|
18243
18470
|
throw new NSGetterRuntimeError(
|
|
18244
18471
|
`OnChanged handler '${listener.memberId}' cannot accept the value of '${slot.member.name}' on '${owner.id}'.`
|
|
18245
18472
|
);
|
|
18473
|
+
if (getter !== null) {
|
|
18474
|
+
editGetterSubscription(
|
|
18475
|
+
getter,
|
|
18476
|
+
handler.target,
|
|
18477
|
+
ins.type === "addChangeListener" /* addChangeListener */,
|
|
18478
|
+
ctx
|
|
18479
|
+
);
|
|
18480
|
+
return;
|
|
18481
|
+
}
|
|
18246
18482
|
options.writes.push({
|
|
18247
18483
|
kind: "changeListener",
|
|
18248
18484
|
target: ins.target,
|
|
@@ -18252,6 +18488,106 @@ function evalChangeListenerInstruction(ins, scope, ctx, options) {
|
|
|
18252
18488
|
listener: handler.target
|
|
18253
18489
|
});
|
|
18254
18490
|
}
|
|
18491
|
+
function editGetterSubscription(slot, target, add, ctx) {
|
|
18492
|
+
if ((ctx.__executionState?.constructionStack.length ?? 0) > 0)
|
|
18493
|
+
throw new NSGetterRuntimeError(
|
|
18494
|
+
"A getter subscription lives only for the play session, so a constructor can't make one. Subscribe from a function."
|
|
18495
|
+
);
|
|
18496
|
+
const subscriptions = ctx.__getterSubscriptions;
|
|
18497
|
+
if (subscriptions === void 0) return;
|
|
18498
|
+
let subscription = subscriptions.get(slot.owner.id, slot.memberId);
|
|
18499
|
+
const found = subscription?.targets.findIndex(
|
|
18500
|
+
(existing) => existing.memberId === target.memberId && existing.valueId === target.valueId
|
|
18501
|
+
) ?? -1;
|
|
18502
|
+
if (!add) {
|
|
18503
|
+
if (subscription === void 0 || found < 0) return;
|
|
18504
|
+
subscription.targets.splice(found, 1);
|
|
18505
|
+
if (subscription.targets.length === 0) subscriptions.drop(subscription);
|
|
18506
|
+
return;
|
|
18507
|
+
}
|
|
18508
|
+
if (found >= 0) return;
|
|
18509
|
+
if (subscription === void 0) {
|
|
18510
|
+
subscription = new NeoScriptGetterSubscription(
|
|
18511
|
+
slot.owner.id,
|
|
18512
|
+
slot.memberId,
|
|
18513
|
+
slot.owner.classId
|
|
18514
|
+
);
|
|
18515
|
+
subscriptions.add(subscription);
|
|
18516
|
+
}
|
|
18517
|
+
subscription.targets.push(target);
|
|
18518
|
+
}
|
|
18519
|
+
function clearGetterSubscription(slot, ctx) {
|
|
18520
|
+
if ((ctx.__executionState?.constructionStack.length ?? 0) > 0)
|
|
18521
|
+
throw new NSGetterRuntimeError(
|
|
18522
|
+
"A getter subscription lives only for the play session, so a constructor can't clear one. Clear from a function."
|
|
18523
|
+
);
|
|
18524
|
+
const subscriptions = ctx.__getterSubscriptions;
|
|
18525
|
+
const subscription = subscriptions?.get(slot.owner.id, slot.memberId);
|
|
18526
|
+
if (subscriptions === void 0 || subscription === void 0) return;
|
|
18527
|
+
subscription.targets.length = 0;
|
|
18528
|
+
subscriptions.drop(subscription);
|
|
18529
|
+
}
|
|
18530
|
+
function dispatchGetterSubscriptions(ctx) {
|
|
18531
|
+
const subscriptions = ctx.__getterSubscriptions;
|
|
18532
|
+
if (subscriptions === void 0) return;
|
|
18533
|
+
const draining = subscriptions.takePending();
|
|
18534
|
+
let next = 0;
|
|
18535
|
+
try {
|
|
18536
|
+
while (next < draining.length)
|
|
18537
|
+
dispatchGetterSubscription(draining[next++], subscriptions, ctx);
|
|
18538
|
+
} finally {
|
|
18539
|
+
subscriptions.requeue(draining, next);
|
|
18540
|
+
}
|
|
18541
|
+
}
|
|
18542
|
+
function dispatchGetterSubscription(subscription, subscriptions, ctx) {
|
|
18543
|
+
subscription.queued = false;
|
|
18544
|
+
const notify = !subscription.arming;
|
|
18545
|
+
subscription.arming = false;
|
|
18546
|
+
if (subscription.targets.length === 0) return;
|
|
18547
|
+
const slot = resolveNeoScriptGetterListenerSlot(
|
|
18548
|
+
subscription.rowId,
|
|
18549
|
+
subscription.getterId,
|
|
18550
|
+
ctx
|
|
18551
|
+
);
|
|
18552
|
+
if (slot === null || slot.owner.classId !== subscription.classId) {
|
|
18553
|
+
subscriptions.drop(subscription);
|
|
18554
|
+
return;
|
|
18555
|
+
}
|
|
18556
|
+
const reads = new InitializerReadSet();
|
|
18557
|
+
let value;
|
|
18558
|
+
try {
|
|
18559
|
+
value = readNeoScriptChangeListenerValue(slot, {
|
|
18560
|
+
...ctx,
|
|
18561
|
+
__getterReads: reads.valueIds,
|
|
18562
|
+
containerDependencies: reads.containerIds,
|
|
18563
|
+
staticMemberDependencies: reads.staticMemberIds,
|
|
18564
|
+
worldQueryDependencies: reads.worldQueries,
|
|
18565
|
+
onUnattributableValueRead: reads.recordUnattributableValueRead
|
|
18566
|
+
});
|
|
18567
|
+
} finally {
|
|
18568
|
+
subscriptions.setReads(subscription, reads);
|
|
18569
|
+
}
|
|
18570
|
+
if (!notify) return;
|
|
18571
|
+
const owner = readRowValue(slot.owner, ctx);
|
|
18572
|
+
subscription.handling = true;
|
|
18573
|
+
try {
|
|
18574
|
+
for (const target of [...subscription.targets]) {
|
|
18575
|
+
const handler = resolveNeoScriptChangeListenerHandler(slot, target, ctx);
|
|
18576
|
+
if (handler === null) continue;
|
|
18577
|
+
invokeDelegateValue(
|
|
18578
|
+
handler.invocation,
|
|
18579
|
+
[value],
|
|
18580
|
+
ctx,
|
|
18581
|
+
void 0,
|
|
18582
|
+
owner,
|
|
18583
|
+
"discarded",
|
|
18584
|
+
() => dispatchGetterSubscriptions(ctx)
|
|
18585
|
+
);
|
|
18586
|
+
}
|
|
18587
|
+
} finally {
|
|
18588
|
+
subscription.handling = false;
|
|
18589
|
+
}
|
|
18590
|
+
}
|
|
18255
18591
|
function evalActionListenerInstruction(ins, scope, ctx, options) {
|
|
18256
18592
|
const operator = ins.type === "addActionListener" /* addActionListener */ ? "+=" : "-=";
|
|
18257
18593
|
if (ins.target.pointer.type === "variable" /* variable */) {
|
|
@@ -18428,6 +18764,7 @@ function applyOverlayStaticAssignment(memberId, value, ctx) {
|
|
|
18428
18764
|
);
|
|
18429
18765
|
}
|
|
18430
18766
|
const bindings = writableStaticBindingMap(member, ctx);
|
|
18767
|
+
ctx.__getterSubscriptions?.noteStaticBinding(member.id);
|
|
18431
18768
|
if (value === null || value === void 0) {
|
|
18432
18769
|
if (isRequiredMember(member)) {
|
|
18433
18770
|
throw new NSGetterRuntimeError(
|
|
@@ -18466,7 +18803,7 @@ function applyOverlayStaticAssignment(memberId, value, ctx) {
|
|
|
18466
18803
|
`Static member '${member.name}' is bound to missing value '${currentId}'.`
|
|
18467
18804
|
);
|
|
18468
18805
|
}
|
|
18469
|
-
ctx
|
|
18806
|
+
observeValueWrite(ctx, row2);
|
|
18470
18807
|
row2.value = value;
|
|
18471
18808
|
row2.updatedAt = Date.now();
|
|
18472
18809
|
invalidateEvaluatorIndexes(ctx);
|
|
@@ -25281,14 +25618,14 @@ function evalVariantApply(info, scope, ctx) {
|
|
|
25281
25618
|
});
|
|
25282
25619
|
for (const valueId of resolution.clearedValueIds) {
|
|
25283
25620
|
const previous = readNeoScriptRuntimeRow(ctx, valueId);
|
|
25284
|
-
if (previous) ctx
|
|
25621
|
+
if (previous) observeValueWrite(ctx, previous);
|
|
25285
25622
|
deleteRuntimeSessionValue(ctx, valueId);
|
|
25286
25623
|
ctx.__valueOverlay?.delete(valueId);
|
|
25287
25624
|
}
|
|
25288
25625
|
for (const row of resolution.rows) {
|
|
25289
25626
|
if (row.id === rootRow.id) continue;
|
|
25290
25627
|
const previous = readNeoScriptRuntimeRow(ctx, row.id);
|
|
25291
|
-
if (previous) ctx
|
|
25628
|
+
if (previous) observeValueWrite(ctx, previous);
|
|
25292
25629
|
ctx.__valueOverlay?.set(row.id, deepClonePlainData(row));
|
|
25293
25630
|
}
|
|
25294
25631
|
if (typeof receiver !== "object" || receiver === null || Array.isArray(receiver) || typeof resolution.root.value !== "object" || resolution.root.value === null || Array.isArray(resolution.root.value)) {
|
|
@@ -26506,7 +26843,7 @@ function cloneClassValueGraph(receiver, expectedClassId, ctx) {
|
|
|
26506
26843
|
const edit = editChangeListenerSet(
|
|
26507
26844
|
entry?.[write.memberId],
|
|
26508
26845
|
[],
|
|
26509
|
-
|
|
26846
|
+
changeListenerWriteEdit(write),
|
|
26510
26847
|
{ inheritedComplete: false }
|
|
26511
26848
|
);
|
|
26512
26849
|
if (!edit.changed) continue;
|
|
@@ -33731,6 +34068,15 @@ function inspectListenerAnnotation(annotation2, parameters) {
|
|
|
33731
34068
|
return;
|
|
33732
34069
|
}
|
|
33733
34070
|
const parameter3 = parameters.byName.get(name);
|
|
34071
|
+
if (!parameter3 && parameters.getters.has(name)) {
|
|
34072
|
+
errors.push(
|
|
34073
|
+
new CompileError(
|
|
34074
|
+
`'${name}' is a getter. Getter listeners can't be authored. Subscribe with '+=' from a function.`,
|
|
34075
|
+
expression.pos
|
|
34076
|
+
)
|
|
34077
|
+
);
|
|
34078
|
+
return;
|
|
34079
|
+
}
|
|
33734
34080
|
if (!parameter3) {
|
|
33735
34081
|
errors.push(
|
|
33736
34082
|
new CompileError(
|
|
@@ -33774,7 +34120,10 @@ function createListenerAnnotationProvider(project, context = {}) {
|
|
|
33774
34120
|
if (cached) return cached;
|
|
33775
34121
|
const parameters = [];
|
|
33776
34122
|
const byName = /* @__PURE__ */ new Map();
|
|
34123
|
+
const getters = /* @__PURE__ */ new Set();
|
|
33777
34124
|
for (const symbol of declaration.members) {
|
|
34125
|
+
if (symbol.kind === "property" && symbol.computed === true && symbol.static !== true)
|
|
34126
|
+
getters.add(symbol.name);
|
|
33778
34127
|
if (!isChangeListenerSymbol(symbol)) continue;
|
|
33779
34128
|
if (memberAccessFailure({ project, context, owner: declaration, symbol }))
|
|
33780
34129
|
continue;
|
|
@@ -33798,7 +34147,8 @@ function createListenerAnnotationProvider(project, context = {}) {
|
|
|
33798
34147
|
const result = {
|
|
33799
34148
|
namedOnly: true,
|
|
33800
34149
|
parameters,
|
|
33801
|
-
byName
|
|
34150
|
+
byName,
|
|
34151
|
+
getters
|
|
33802
34152
|
};
|
|
33803
34153
|
cache.set(key, result);
|
|
33804
34154
|
return result;
|
|
@@ -34020,6 +34370,7 @@ var WRITE_TARGET_DESCRIPTIONS = {
|
|
|
34020
34370
|
projectValue: "a stored project value",
|
|
34021
34371
|
unknown: "something other than `this` or a local"
|
|
34022
34372
|
};
|
|
34373
|
+
var ON_CHANGED_OPERATIONS_ERROR = "OnChanged supports only '+=', '-=', and Clear().";
|
|
34023
34374
|
var FALLTHROUGH_LABELS = {
|
|
34024
34375
|
function: "NSFunction",
|
|
34025
34376
|
getter: "getter",
|
|
@@ -35362,6 +35713,12 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
35362
35713
|
this.resolveExpression(statement.expr, scope);
|
|
35363
35714
|
const debug = this.resolveDebugStatement(statement.expr, scope);
|
|
35364
35715
|
if (debug) return debug;
|
|
35716
|
+
const listenerClear = this.resolveChangeListenerClear(
|
|
35717
|
+
statement.expr,
|
|
35718
|
+
scope,
|
|
35719
|
+
statement.pos
|
|
35720
|
+
);
|
|
35721
|
+
if (listenerClear) return listenerClear;
|
|
35365
35722
|
const actionClear = this.resolveActionClear(
|
|
35366
35723
|
statement.expr,
|
|
35367
35724
|
scope,
|
|
@@ -35722,8 +36079,20 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
35722
36079
|
const observed = this.resolveExpression(statement.target.receiver, scope);
|
|
35723
36080
|
const observedType = neoScriptMemberLookupType(observed.type);
|
|
35724
36081
|
const declared = observedType.kind === "named" && this.project.typeById.get(observedType.typeId)?.members.some((member) => member.name === "OnChanged");
|
|
35725
|
-
if (!declared)
|
|
35726
|
-
|
|
36082
|
+
if (!declared) {
|
|
36083
|
+
if (statement.op !== "+=" && statement.op !== "-=")
|
|
36084
|
+
throw new CompileError(ON_CHANGED_OPERATIONS_ERROR, statement.pos);
|
|
36085
|
+
return this.resolveChangeListener(
|
|
36086
|
+
statement.target,
|
|
36087
|
+
observed,
|
|
36088
|
+
scope,
|
|
36089
|
+
statement.pos,
|
|
36090
|
+
{
|
|
36091
|
+
kind: statement.op === "+=" ? "addChangeListener" /* AddChangeListener */ : "removeChangeListener" /* RemoveChangeListener */,
|
|
36092
|
+
handler: statement.value
|
|
36093
|
+
}
|
|
36094
|
+
);
|
|
36095
|
+
}
|
|
35727
36096
|
}
|
|
35728
36097
|
const local = statement.target.kind === "ident" ? scope.lookup(statement.target.name) : null;
|
|
35729
36098
|
if (local?.readonlyBinding) {
|
|
@@ -35907,112 +36276,180 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
35907
36276
|
pos
|
|
35908
36277
|
);
|
|
35909
36278
|
}
|
|
35910
|
-
|
|
35911
|
-
|
|
35912
|
-
|
|
35913
|
-
|
|
35914
|
-
|
|
35915
|
-
|
|
35916
|
-
|
|
35917
|
-
if (
|
|
36279
|
+
/** `X.M.OnChanged.Clear()` empties M's listener set on X (P70, P106). */
|
|
36280
|
+
resolveChangeListenerClear(expression, scope, pos) {
|
|
36281
|
+
if (expression.kind !== "call" || expression.callee.kind !== "member" || expression.callee.name !== "Clear" || expression.callee.receiver.kind !== "member" || expression.callee.receiver.name !== "OnChanged")
|
|
36282
|
+
return null;
|
|
36283
|
+
const onChanged = expression.callee.receiver;
|
|
36284
|
+
const observed = this.resolveExpression(onChanged.receiver, scope);
|
|
36285
|
+
const observedType = neoScriptMemberLookupType(observed.type);
|
|
36286
|
+
if (observedType.kind === "named" && this.project.typeById.get(observedType.typeId)?.members.some((member) => member.name === "OnChanged"))
|
|
36287
|
+
return null;
|
|
36288
|
+
if (expression.callee.optional)
|
|
35918
36289
|
throw new CompileError(
|
|
35919
|
-
"OnChanged
|
|
35920
|
-
|
|
36290
|
+
"OnChanged is never null, so optional-chained Clear is not supported.",
|
|
36291
|
+
pos
|
|
35921
36292
|
);
|
|
35922
|
-
|
|
35923
|
-
|
|
36293
|
+
requireArgCount("Clear", expression.args, 0, pos);
|
|
36294
|
+
return this.resolveChangeListener(onChanged, observed, scope, pos, {
|
|
36295
|
+
kind: "clearChangeListeners" /* ClearChangeListeners */
|
|
36296
|
+
});
|
|
36297
|
+
}
|
|
36298
|
+
resolveChangeListener(onChanged, observed, scope, pos, edit) {
|
|
36299
|
+
if (onChanged.optional) {
|
|
35924
36300
|
throw new CompileError(
|
|
35925
36301
|
"OnChanged cannot use an optional subscription target.",
|
|
35926
|
-
|
|
36302
|
+
pos
|
|
35927
36303
|
);
|
|
35928
36304
|
}
|
|
35929
36305
|
if (observed.optionalChainType !== void 0) {
|
|
35930
36306
|
throw new CompileError(
|
|
35931
36307
|
"OnChanged cannot subscribe through optional chaining; narrow the receiver first.",
|
|
35932
|
-
|
|
36308
|
+
pos
|
|
35933
36309
|
);
|
|
35934
36310
|
}
|
|
35935
36311
|
const member = observed.symbol;
|
|
35936
36312
|
if (!member)
|
|
35937
36313
|
throw new CompileError(
|
|
35938
36314
|
"OnChanged requires a declared member, not a local variable.",
|
|
35939
|
-
|
|
36315
|
+
pos
|
|
35940
36316
|
);
|
|
35941
|
-
if (observed.pointer.type
|
|
36317
|
+
if (observed.pointer.type === "staticMember" /* StaticMember */ || observed.pointer.type === "callGetter" /* CallGetter */ && observed.pointer.receiver.kind === "static") {
|
|
36318
|
+
const access = onChanged.receiver;
|
|
36319
|
+
const name = access.kind === "member" && access.receiver.kind === "ident" ? `${access.receiver.name}.${member.name}` : member.name;
|
|
35942
36320
|
throw new CompileError(
|
|
35943
|
-
|
|
35944
|
-
|
|
36321
|
+
`OnChanged requires an instance member. '${name}' is static.`,
|
|
36322
|
+
pos
|
|
36323
|
+
);
|
|
36324
|
+
}
|
|
36325
|
+
if (observed.pointer.type === "callGetter" /* CallGetter */)
|
|
36326
|
+
return this.resolveGetterChangeListener(
|
|
36327
|
+
onChanged.receiver,
|
|
36328
|
+
observed,
|
|
36329
|
+
observed.pointer,
|
|
36330
|
+
member,
|
|
36331
|
+
scope,
|
|
36332
|
+
pos,
|
|
36333
|
+
edit
|
|
35945
36334
|
);
|
|
36335
|
+
if (observed.pointer.type !== "keyOf" /* KeyOf */)
|
|
36336
|
+
throw new CompileError("OnChanged requires a declared member slot.", pos);
|
|
35946
36337
|
if (!observed.pointer.memberId)
|
|
35947
36338
|
throw new CompileError(
|
|
35948
36339
|
"OnChanged cannot observe a collection entry.",
|
|
35949
|
-
|
|
36340
|
+
pos
|
|
35950
36341
|
);
|
|
35951
36342
|
if (member.computed) {
|
|
35952
36343
|
throw new CompileError(
|
|
35953
36344
|
"OnChanged cannot observe a computed member.",
|
|
35954
|
-
|
|
36345
|
+
pos
|
|
35955
36346
|
);
|
|
35956
36347
|
}
|
|
35957
36348
|
if (member.readonlyDeclaration) {
|
|
35958
36349
|
throw new CompileError(
|
|
35959
36350
|
"OnChanged cannot observe a readonly declaration.",
|
|
35960
|
-
|
|
36351
|
+
pos
|
|
35961
36352
|
);
|
|
35962
36353
|
}
|
|
35963
36354
|
if (observed.type.kind === "delegate" || observed.type.kind === "action") {
|
|
35964
36355
|
throw new CompileError(
|
|
35965
36356
|
"OnChanged cannot observe a callable member.",
|
|
35966
|
-
|
|
36357
|
+
pos
|
|
35967
36358
|
);
|
|
35968
36359
|
}
|
|
35969
36360
|
const writability = observed.userData ? "runtime" /* Runtime */ : observed.writability;
|
|
35970
36361
|
if (writability !== "save" /* Save */ && writability !== "session" /* Session */ && writability !== "runtime" /* Runtime */ && writability !== "local" /* Local */) {
|
|
35971
36362
|
throw new CompileError(
|
|
35972
36363
|
"OnChanged requires a member whose storage is writable at gameplay runtime.",
|
|
35973
|
-
|
|
36364
|
+
pos
|
|
35974
36365
|
);
|
|
35975
36366
|
}
|
|
35976
36367
|
this.validateConstructorWriteTarget(
|
|
35977
36368
|
observed.pointer,
|
|
35978
|
-
"subscribe to",
|
|
35979
|
-
|
|
36369
|
+
edit.kind === "clearChangeListeners" /* ClearChangeListeners */ ? "clear listeners on" : "subscribe to",
|
|
36370
|
+
pos,
|
|
35980
36371
|
scope,
|
|
35981
36372
|
false
|
|
35982
36373
|
);
|
|
35983
|
-
|
|
36374
|
+
const storageType = this.assignmentStorageType(
|
|
36375
|
+
onChanged.receiver,
|
|
36376
|
+
observed,
|
|
36377
|
+
null,
|
|
36378
|
+
scope
|
|
36379
|
+
);
|
|
36380
|
+
return this.changeListenerInstruction(
|
|
36381
|
+
edit,
|
|
36382
|
+
{
|
|
36383
|
+
owner: observed.pointer.keyOf.pointer,
|
|
36384
|
+
memberId: member.canonicalMemberId ?? observed.pointer.memberId,
|
|
36385
|
+
typeInfo: toWireType(storageType, this.project),
|
|
36386
|
+
writability
|
|
36387
|
+
},
|
|
36388
|
+
storageType,
|
|
36389
|
+
scope,
|
|
36390
|
+
pos
|
|
36391
|
+
);
|
|
36392
|
+
}
|
|
36393
|
+
/**
|
|
36394
|
+
* P106. A getter subscription lives only in the running client's memory:
|
|
36395
|
+
* nothing persists it, so construction replay would silently drop one.
|
|
36396
|
+
*/
|
|
36397
|
+
resolveGetterChangeListener(getterRead, observed, pointer, member, scope, pos, edit) {
|
|
36398
|
+
if (pointer.dispatch === "base") {
|
|
35984
36399
|
throw new CompileError(
|
|
35985
|
-
|
|
35986
|
-
|
|
36400
|
+
`OnChanged can't observe a base getter. Subscribe to '${member.name}' on the instance.`,
|
|
36401
|
+
pos
|
|
35987
36402
|
);
|
|
35988
36403
|
}
|
|
35989
|
-
|
|
35990
|
-
|
|
36404
|
+
if (pointer.receiver.kind !== "instance") {
|
|
36405
|
+
throw new CompileError(
|
|
36406
|
+
`OnChanged requires an instance receiver for getter '${member.name}'.`,
|
|
36407
|
+
pos
|
|
36408
|
+
);
|
|
36409
|
+
}
|
|
36410
|
+
const kind = this.context.kind;
|
|
36411
|
+
if (isNeoScriptConstructionDocumentKind(kind) || kind === "migration") {
|
|
36412
|
+
throw new CompileError(
|
|
36413
|
+
edit.kind === "clearChangeListeners" /* ClearChangeListeners */ ? `A getter subscription lives only for the play session, so ${dialogueBodyKindLabel(kind)} can't clear one. Clear from a function.` : `A getter subscription lives only for the play session, so ${dialogueBodyKindLabel(kind)} can't make one. Subscribe from a function.`,
|
|
36414
|
+
pos
|
|
36415
|
+
);
|
|
36416
|
+
}
|
|
36417
|
+
const getterType = this.assignmentStorageType(
|
|
36418
|
+
getterRead,
|
|
35991
36419
|
observed,
|
|
35992
36420
|
null,
|
|
35993
36421
|
scope
|
|
35994
36422
|
);
|
|
35995
|
-
|
|
35996
|
-
|
|
35997
|
-
|
|
35998
|
-
|
|
36423
|
+
return this.changeListenerInstruction(
|
|
36424
|
+
edit,
|
|
36425
|
+
{
|
|
36426
|
+
owner: pointer.receiver.pointer,
|
|
36427
|
+
memberId: member.canonicalMemberId ?? pointer.memberId,
|
|
36428
|
+
typeInfo: toWireType(getterType, this.project),
|
|
36429
|
+
writability: "session" /* Session */
|
|
36430
|
+
},
|
|
36431
|
+
getterType,
|
|
36432
|
+
scope,
|
|
36433
|
+
pos
|
|
36434
|
+
);
|
|
36435
|
+
}
|
|
36436
|
+
changeListenerInstruction(edit, target, observedType, scope, pos) {
|
|
36437
|
+
if (edit.kind === "clearChangeListeners" /* ClearChangeListeners */)
|
|
36438
|
+
return { type: edit.kind, target };
|
|
36439
|
+
if (!edit.handler) {
|
|
36440
|
+
throw new CompileError(
|
|
36441
|
+
"OnChanged subscription requires a handler member.",
|
|
36442
|
+
pos
|
|
36443
|
+
);
|
|
36444
|
+
}
|
|
35999
36445
|
const listener = this.resolveActionListener(
|
|
36000
|
-
|
|
36001
|
-
|
|
36446
|
+
edit.handler,
|
|
36447
|
+
{ kind: "action", parameterTypes: [observedType] },
|
|
36002
36448
|
scope,
|
|
36003
36449
|
true,
|
|
36004
36450
|
true
|
|
36005
36451
|
);
|
|
36006
|
-
return {
|
|
36007
|
-
type: statement.op === "+=" ? "addChangeListener" /* AddChangeListener */ : "removeChangeListener" /* RemoveChangeListener */,
|
|
36008
|
-
target: {
|
|
36009
|
-
owner: observed.pointer.keyOf.pointer,
|
|
36010
|
-
memberId: member.canonicalMemberId ?? observed.pointer.memberId,
|
|
36011
|
-
typeInfo: toWireType(storageType, this.project),
|
|
36012
|
-
writability
|
|
36013
|
-
},
|
|
36014
|
-
listener
|
|
36015
|
-
};
|
|
36452
|
+
return { type: edit.kind, target, listener };
|
|
36016
36453
|
}
|
|
36017
36454
|
/**
|
|
36018
36455
|
* P62 §3.2. `+=` / `-=` on an NSAction member are subscription operators,
|
|
@@ -38130,6 +38567,8 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
38130
38567
|
entryUserData
|
|
38131
38568
|
};
|
|
38132
38569
|
}
|
|
38570
|
+
if (name === "OnChanged")
|
|
38571
|
+
throw new CompileError(ON_CHANGED_OPERATIONS_ERROR, pos);
|
|
38133
38572
|
throw new CompileError(
|
|
38134
38573
|
`Cannot read member '${name}' on ${this.describe(receiver.type)}`,
|
|
38135
38574
|
pos
|
|
@@ -51186,7 +51625,7 @@ var ACTION_LISTENER_TARGET_KINDS = /* @__PURE__ */ new Set([
|
|
|
51186
51625
|
26 /* NSAction */
|
|
51187
51626
|
]);
|
|
51188
51627
|
|
|
51189
|
-
// node_modules/valibot/dist/index.mjs
|
|
51628
|
+
// ../node_modules/valibot/dist/index.mjs
|
|
51190
51629
|
var store$4;
|
|
51191
51630
|
var DEFAULT_CONFIG = {
|
|
51192
51631
|
lang: void 0,
|
|
@@ -51274,18 +51713,6 @@ function _standardSchema(schema) {
|
|
|
51274
51713
|
};
|
|
51275
51714
|
return schema;
|
|
51276
51715
|
}
|
|
51277
|
-
var ValiError = class extends Error {
|
|
51278
|
-
/**
|
|
51279
|
-
* Creates a Valibot error with useful information.
|
|
51280
|
-
*
|
|
51281
|
-
* @param issues The error issues.
|
|
51282
|
-
*/
|
|
51283
|
-
constructor(issues) {
|
|
51284
|
-
super(issues[0].message);
|
|
51285
|
-
this.name = "ValiError";
|
|
51286
|
-
this.issues = issues;
|
|
51287
|
-
}
|
|
51288
|
-
};
|
|
51289
51716
|
var EMOJI_REGEX = new RegExp("^(?:[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|(?![\\p{Emoji_Modifier_Base}\\u{1F1E6}-\\u{1F1FF}])\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|(?![\\p{Emoji_Modifier_Base}\\u{1F1E6}-\\u{1F1FF}])\\p{Emoji_Presentation}))*)+$", "u");
|
|
51290
51717
|
// @__NO_SIDE_EFFECTS__
|
|
51291
51718
|
function check(requirement, message$1) {
|
|
@@ -51956,11 +52383,6 @@ function variant(key, options, message$1) {
|
|
|
51956
52383
|
}
|
|
51957
52384
|
});
|
|
51958
52385
|
}
|
|
51959
|
-
function parse2(schema, input, config$1) {
|
|
51960
|
-
const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig(config$1));
|
|
51961
|
-
if (dataset.issues) throw new ValiError(dataset.issues);
|
|
51962
|
-
return dataset.value;
|
|
51963
|
-
}
|
|
51964
52386
|
// @__NO_SIDE_EFFECTS__
|
|
51965
52387
|
function pipe(...pipe$1) {
|
|
51966
52388
|
return _standardSchema({
|
|
@@ -52584,6 +53006,43 @@ var schemaMemberSchema = variant("kind", [
|
|
|
52584
53006
|
})
|
|
52585
53007
|
]);
|
|
52586
53008
|
|
|
53009
|
+
// node_modules/valibot/dist/index.mjs
|
|
53010
|
+
var store$42;
|
|
53011
|
+
var DEFAULT_CONFIG2 = {
|
|
53012
|
+
lang: void 0,
|
|
53013
|
+
message: void 0,
|
|
53014
|
+
abortEarly: void 0,
|
|
53015
|
+
abortPipeEarly: void 0
|
|
53016
|
+
};
|
|
53017
|
+
// @__NO_SIDE_EFFECTS__
|
|
53018
|
+
function getGlobalConfig2(config$1) {
|
|
53019
|
+
if (!config$1 && !store$42) return DEFAULT_CONFIG2;
|
|
53020
|
+
return {
|
|
53021
|
+
lang: config$1?.lang ?? store$42?.lang,
|
|
53022
|
+
message: config$1?.message,
|
|
53023
|
+
abortEarly: config$1?.abortEarly ?? store$42?.abortEarly,
|
|
53024
|
+
abortPipeEarly: config$1?.abortPipeEarly ?? store$42?.abortPipeEarly
|
|
53025
|
+
};
|
|
53026
|
+
}
|
|
53027
|
+
var ValiError = class extends Error {
|
|
53028
|
+
/**
|
|
53029
|
+
* Creates a Valibot error with useful information.
|
|
53030
|
+
*
|
|
53031
|
+
* @param issues The error issues.
|
|
53032
|
+
*/
|
|
53033
|
+
constructor(issues) {
|
|
53034
|
+
super(issues[0].message);
|
|
53035
|
+
this.name = "ValiError";
|
|
53036
|
+
this.issues = issues;
|
|
53037
|
+
}
|
|
53038
|
+
};
|
|
53039
|
+
var EMOJI_REGEX2 = new RegExp("^(?:[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|(?![\\p{Emoji_Modifier_Base}\\u{1F1E6}-\\u{1F1FF}])\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|(?![\\p{Emoji_Modifier_Base}\\u{1F1E6}-\\u{1F1FF}])\\p{Emoji_Presentation}))*)+$", "u");
|
|
53040
|
+
function parse2(schema, input, config$1) {
|
|
53041
|
+
const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig2(config$1));
|
|
53042
|
+
if (dataset.issues) throw new ValiError(dataset.issues);
|
|
53043
|
+
return dataset.value;
|
|
53044
|
+
}
|
|
53045
|
+
|
|
52587
53046
|
// ../packages/neoscript-language/src/docs-text.ts
|
|
52588
53047
|
var DOCS_TEXT_MAX_UTF8_BYTES2 = 16384;
|
|
52589
53048
|
function docsTextUtf8ByteLength(value) {
|
|
@@ -55288,7 +55747,7 @@ var SPECIALIZED_RELATION_KINDS = /* @__PURE__ */ new Set([
|
|
|
55288
55747
|
|
|
55289
55748
|
// ../packages/manifest/schema-contract/registry.mjs
|
|
55290
55749
|
var PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
55291
|
-
cliVersion: "0.
|
|
55750
|
+
cliVersion: "0.75.0",
|
|
55292
55751
|
projectFileUploadBatchSize: 32,
|
|
55293
55752
|
documentRecords: {
|
|
55294
55753
|
member: {
|
|
@@ -57010,7 +57469,7 @@ var PRESIGN_BATCH_SIZE = Math.min(
|
|
|
57010
57469
|
PROJECT_FILE_UPLOAD_BATCH_SIZE
|
|
57011
57470
|
);
|
|
57012
57471
|
|
|
57013
|
-
// node_modules/@formatjs/icu-messageformat-parser/index.js
|
|
57472
|
+
// ../node_modules/@formatjs/icu-messageformat-parser/index.js
|
|
57014
57473
|
var SPACE_SEPARATOR_REGEX = /[ \xA0\u1680\u2000-\u200A\u202F\u205F\u3000]/;
|
|
57015
57474
|
var IDENTIFIER_PREFIX_REGEX = /([^\t-\r -\/:-@\[-\^`\{-~\x85\xA0-\xA7\xA9\xAB\xAC\xAE\xB0\xB1\xB6\xBB\xBF\xD7\xF7\u1680\u2000-\u200A\u2010-\u2029\u202F-\u203E\u2041-\u2053\u2055-\u205F\u2190-\u245F\u2500-\u2775\u2794-\u2BFF\u2E00-\u2E7F\u3000-\u3003\u3008-\u3020\u3030\uFD3E\uFD3F\uFE45\uFE46]*)/g;
|
|
57016
57475
|
var SPACE_SEPARATOR_START_REGEX = new RegExp(`^${SPACE_SEPARATOR_REGEX.source}*`);
|
|
@@ -57270,7 +57729,8 @@ function makeEvaluatorContext(rawDocument, interceptor) {
|
|
|
57270
57729
|
rootValue: base.rootValue,
|
|
57271
57730
|
dialogueContext: null,
|
|
57272
57731
|
callInterceptor: interceptor,
|
|
57273
|
-
nativeFunctionErrorCheckBehavior: "strict"
|
|
57732
|
+
nativeFunctionErrorCheckBehavior: "strict",
|
|
57733
|
+
getterDispatch: "afterEntryStatement" /* AfterEntryStatement */
|
|
57274
57734
|
});
|
|
57275
57735
|
}
|
|
57276
57736
|
function createSpecCompiler(document2) {
|
|
@@ -57844,6 +58304,7 @@ function copyMocks(source, target) {
|
|
|
57844
58304
|
function cloneTestEnvironment(source) {
|
|
57845
58305
|
const cloned = createTestEnvironment(snapshotEnvironmentDocument(source));
|
|
57846
58306
|
copyMocks(source, cloned);
|
|
58307
|
+
cloned.context.__getterSubscriptions = source.context.__getterSubscriptions?.clone();
|
|
57847
58308
|
return cloned;
|
|
57848
58309
|
}
|
|
57849
58310
|
function runCallback(environment, delegate, deadlineMs) {
|