@ai-ecoverse/slicc-kernel 1.76.0 → 1.77.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.
@@ -1117,6 +1117,142 @@ var init_physical_path = __esm({
1117
1117
  }
1118
1118
  });
1119
1119
 
1120
+ // src/realm/sync-sab-wire.ts
1121
+ function loadU53(header, lo, hi) {
1122
+ return (Atomics.load(header, lo) >>> 0) + Atomics.load(header, hi) * U32;
1123
+ }
1124
+ function publishMemory(sab, bytes) {
1125
+ if (bytes > 0)
1126
+ Atomics.store(new Int32Array(sab, 0, SAB_HEADER_I32), SAB_I_MEMORY, Math.ceil(bytes / 65536));
1127
+ }
1128
+ function decodeSabResult(status2, payload) {
1129
+ switch (status2) {
1130
+ case SAB_STATUS_BYTES:
1131
+ return { ok: true, kind: "bytes", bytes: payload };
1132
+ case SAB_STATUS_VOID:
1133
+ return { ok: true, kind: "void" };
1134
+ case SAB_STATUS_JSON: {
1135
+ try {
1136
+ return { ok: true, kind: "json", json: JSON.parse(decoder.decode(payload)) };
1137
+ } catch {
1138
+ return { ok: false, errno: "EIO", message: "sync-sab: malformed json payload" };
1139
+ }
1140
+ }
1141
+ case SAB_STATUS_ERRNO: {
1142
+ try {
1143
+ const parsed = JSON.parse(decoder.decode(payload));
1144
+ const errno2 = typeof parsed.errno === "string" && /^E[A-Z]+$|^EAI_[A-Z]+$/.test(parsed.errno) ? parsed.errno : "EIO";
1145
+ return { ok: false, errno: errno2, message: String(parsed.message ?? errno2) };
1146
+ } catch {
1147
+ return { ok: false, errno: "EIO", message: "sync-sab: malformed errno payload" };
1148
+ }
1149
+ }
1150
+ default:
1151
+ return { ok: false, errno: "EIO", message: `sync-sab: unknown status ${status2}` };
1152
+ }
1153
+ }
1154
+ function sabViews(sab) {
1155
+ if (sab.byteLength < SAB_MIN_BYTES) {
1156
+ throw new Error(`sync-sab: buffer too small (${sab.byteLength} < ${SAB_MIN_BYTES})`);
1157
+ }
1158
+ return {
1159
+ header: new Int32Array(sab, 0, SAB_HEADER_I32),
1160
+ window: new Uint8Array(sab, SAB_HEADER_BYTES)
1161
+ };
1162
+ }
1163
+ var SAB_HEADER_I32, SAB_CLOCK_OFFSET, SAB_CLOCK_I64, SAB_HEADER_BYTES, SAB_I_STATE, SAB_I_SEQ, SAB_I_STATUS, SAB_I_TOTAL, SAB_I_CHUNK, SAB_I_OFFSET, SAB_I_REQ, SAB_I_PUB, SAB_I_SIGNALS, SAB_I_TIMERS, SAB_I_MEMORY, SAB_I_TOTAL_HI, SAB_I_OFFSET_HI, SAB_I_KILLED, SAB_I_ASYNC, SAB_I_STOP, U32, SAB_STATE_IDLE, SAB_STATE_PENDING, SAB_STATE_READY, SAB_STATUS_BYTES, SAB_STATUS_JSON, SAB_STATUS_VOID, SAB_STATUS_ERRNO, SAB_DEFAULT_WINDOW_BYTES, SAB_MIN_BYTES, SYNC_SAB_REQ_MSG, SYNC_SAB_NEXT_MSG, encoder, decoder;
1164
+ var init_sync_sab_wire = __esm({
1165
+ "src/realm/sync-sab-wire.ts"() {
1166
+ "use strict";
1167
+ SAB_HEADER_I32 = 16;
1168
+ SAB_CLOCK_OFFSET = SAB_HEADER_I32 * 4;
1169
+ SAB_CLOCK_I64 = 3;
1170
+ SAB_HEADER_BYTES = SAB_CLOCK_OFFSET + SAB_CLOCK_I64 * 8;
1171
+ SAB_I_STATE = 0;
1172
+ SAB_I_SEQ = 1;
1173
+ SAB_I_STATUS = 2;
1174
+ SAB_I_TOTAL = 3;
1175
+ SAB_I_CHUNK = 4;
1176
+ SAB_I_OFFSET = 5;
1177
+ SAB_I_REQ = 6;
1178
+ SAB_I_PUB = 7;
1179
+ SAB_I_SIGNALS = 8;
1180
+ SAB_I_TIMERS = 9;
1181
+ SAB_I_MEMORY = 10;
1182
+ SAB_I_TOTAL_HI = 11;
1183
+ SAB_I_OFFSET_HI = 12;
1184
+ SAB_I_KILLED = 13;
1185
+ SAB_I_ASYNC = 14;
1186
+ SAB_I_STOP = 15;
1187
+ U32 = 2 ** 32;
1188
+ SAB_STATE_IDLE = 0;
1189
+ SAB_STATE_PENDING = 1;
1190
+ SAB_STATE_READY = 2;
1191
+ SAB_STATUS_BYTES = 1;
1192
+ SAB_STATUS_JSON = 2;
1193
+ SAB_STATUS_VOID = 3;
1194
+ SAB_STATUS_ERRNO = 4;
1195
+ SAB_DEFAULT_WINDOW_BYTES = 1024 * 1024;
1196
+ SAB_MIN_BYTES = SAB_HEADER_BYTES + 4096;
1197
+ SYNC_SAB_REQ_MSG = "sync-sab-req";
1198
+ SYNC_SAB_NEXT_MSG = "sync-sab-next";
1199
+ encoder = new TextEncoder();
1200
+ decoder = new TextDecoder();
1201
+ }
1202
+ });
1203
+
1204
+ // src/kernel/cpu-clock.ts
1205
+ function epochMicros() {
1206
+ return Math.floor((performance.timeOrigin + performance.now()) * 1e3);
1207
+ }
1208
+ function slots(sab) {
1209
+ return new BigInt64Array(sab, LOCAL, SAB_CLOCK_I64);
1210
+ }
1211
+ function useLocalClock(sab) {
1212
+ local = sab && sab.byteLength >= LOCAL + SAB_CLOCK_I64 * 8 ? slots(sab) : void 0;
1213
+ if (!local) return;
1214
+ localSab = sab;
1215
+ localStart = epochMicros();
1216
+ const wait2 = (typed, index3, value2, timeout) => localWait(() => rawWait(typed, index3, value2, timeout));
1217
+ Atomics.wait = wait2;
1218
+ }
1219
+ function localWait(wait2) {
1220
+ const clock = local;
1221
+ if (!clock) return wait2();
1222
+ const start2 = BigInt(epochMicros());
1223
+ const idle = Atomics.load(clock, IDLE);
1224
+ Atomics.store(clock, IDLE, idle - start2);
1225
+ try {
1226
+ return wait2();
1227
+ } finally {
1228
+ const end = BigInt(epochMicros());
1229
+ Atomics.store(clock, IDLE, idle + (end > start2 ? end - start2 : 0n));
1230
+ }
1231
+ }
1232
+ function localCpuNanos() {
1233
+ if (!local || !localSab) return void 0;
1234
+ const now = epochMicros();
1235
+ const blocked = Number(Atomics.load(local, BLOCKED)) + localIdle(localSab, now).idle;
1236
+ return BigInt(Math.max(0, now - localStart - blocked)) * 1000n;
1237
+ }
1238
+ function localIdle(sab, now) {
1239
+ const state = Number(Atomics.load(slots(sab), IDLE));
1240
+ if (state >= 0) return { idle: state, waiting: false };
1241
+ return { idle: Math.max(0, now + state), waiting: true };
1242
+ }
1243
+ var LOCAL, BLOCKED, IDLE, local, localSab, localStart, rawWait;
1244
+ var init_cpu_clock = __esm({
1245
+ "src/kernel/cpu-clock.ts"() {
1246
+ "use strict";
1247
+ init_sync_sab_wire();
1248
+ LOCAL = SAB_CLOCK_OFFSET;
1249
+ BLOCKED = 0;
1250
+ IDLE = 1;
1251
+ localStart = 0;
1252
+ rawWait = Atomics.wait.bind(Atomics);
1253
+ }
1254
+ });
1255
+
1120
1256
  // src/fs/types.ts
1121
1257
  function normalizePath(path) {
1122
1258
  const parts = [];
@@ -2000,11 +2136,11 @@ var init_wasi_fds = __esm({
2000
2136
  });
2001
2137
 
2002
2138
  // src/process/wasi/wasi-memory.ts
2003
- var decoder, WasiMemory;
2139
+ var decoder2, WasiMemory;
2004
2140
  var init_wasi_memory = __esm({
2005
2141
  "src/process/wasi/wasi-memory.ts"() {
2006
2142
  "use strict";
2007
- decoder = new TextDecoder();
2143
+ decoder2 = new TextDecoder();
2008
2144
  WasiMemory = class {
2009
2145
  memory;
2010
2146
  bind(memory) {
@@ -2021,13 +2157,13 @@ var init_wasi_memory = __esm({
2021
2157
  return new Uint8Array(this.buffer(), ptr, len);
2022
2158
  }
2023
2159
  string(ptr, len) {
2024
- return decoder.decode(this.bytes(ptr, len).slice());
2160
+ return decoder2.decode(this.bytes(ptr, len).slice());
2025
2161
  }
2026
2162
  cString(ptr) {
2027
2163
  const bytes = new Uint8Array(this.buffer());
2028
2164
  let end = ptr;
2029
2165
  while (end < bytes.length && bytes[end] !== 0) end++;
2030
- return decoder.decode(bytes.slice(ptr, end));
2166
+ return decoder2.decode(bytes.slice(ptr, end));
2031
2167
  }
2032
2168
  size() {
2033
2169
  return this.buffer().byteLength;
@@ -2347,6 +2483,7 @@ var init_wasi_host = __esm({
2347
2483
  "src/process/wasi/wasi-host.ts"() {
2348
2484
  "use strict";
2349
2485
  init_physical_path();
2486
+ init_cpu_clock();
2350
2487
  init_cred();
2351
2488
  init_wasi_abi();
2352
2489
  init_wasi_fds();
@@ -2610,7 +2747,7 @@ var init_wasi_host = __esm({
2610
2747
  if (id === CLOCK.MONOTONIC) {
2611
2748
  return MONOTONIC_BASE + BigInt(Math.round(performance.now() * 1e6));
2612
2749
  }
2613
- return BigInt(Math.round((performance.now() - this.started) * 1e6)) + 1n;
2750
+ return (localCpuNanos() ?? BigInt(Math.round((performance.now() - this.started) * 1e6))) + 1n;
2614
2751
  }
2615
2752
  environ() {
2616
2753
  const listen2 = this.listening.length > 0 ? { SLICC_LISTEN_FDS: this.listening.join(" ") } : {};
@@ -3535,90 +3672,6 @@ var init_wasi_imports = __esm({
3535
3672
  }
3536
3673
  });
3537
3674
 
3538
- // src/realm/sync-sab-wire.ts
3539
- function loadU53(header, lo, hi) {
3540
- return (Atomics.load(header, lo) >>> 0) + Atomics.load(header, hi) * U32;
3541
- }
3542
- function publishMemory(sab, bytes) {
3543
- if (bytes > 0)
3544
- Atomics.store(new Int32Array(sab, 0, SAB_HEADER_I32), SAB_I_MEMORY, Math.ceil(bytes / 65536));
3545
- }
3546
- function decodeSabResult(status2, payload) {
3547
- switch (status2) {
3548
- case SAB_STATUS_BYTES:
3549
- return { ok: true, kind: "bytes", bytes: payload };
3550
- case SAB_STATUS_VOID:
3551
- return { ok: true, kind: "void" };
3552
- case SAB_STATUS_JSON: {
3553
- try {
3554
- return { ok: true, kind: "json", json: JSON.parse(decoder2.decode(payload)) };
3555
- } catch {
3556
- return { ok: false, errno: "EIO", message: "sync-sab: malformed json payload" };
3557
- }
3558
- }
3559
- case SAB_STATUS_ERRNO: {
3560
- try {
3561
- const parsed = JSON.parse(decoder2.decode(payload));
3562
- const errno2 = typeof parsed.errno === "string" && /^E[A-Z]+$|^EAI_[A-Z]+$/.test(parsed.errno) ? parsed.errno : "EIO";
3563
- return { ok: false, errno: errno2, message: String(parsed.message ?? errno2) };
3564
- } catch {
3565
- return { ok: false, errno: "EIO", message: "sync-sab: malformed errno payload" };
3566
- }
3567
- }
3568
- default:
3569
- return { ok: false, errno: "EIO", message: `sync-sab: unknown status ${status2}` };
3570
- }
3571
- }
3572
- function sabViews(sab) {
3573
- if (sab.byteLength < SAB_MIN_BYTES) {
3574
- throw new Error(`sync-sab: buffer too small (${sab.byteLength} < ${SAB_MIN_BYTES})`);
3575
- }
3576
- return {
3577
- header: new Int32Array(sab, 0, SAB_HEADER_I32),
3578
- window: new Uint8Array(sab, SAB_HEADER_BYTES)
3579
- };
3580
- }
3581
- var SAB_HEADER_I32, SAB_CLOCK_OFFSET, SAB_CLOCK_I64, SAB_HEADER_BYTES, SAB_I_STATE, SAB_I_SEQ, SAB_I_STATUS, SAB_I_TOTAL, SAB_I_CHUNK, SAB_I_OFFSET, SAB_I_REQ, SAB_I_PUB, SAB_I_SIGNALS, SAB_I_TIMERS, SAB_I_MEMORY, SAB_I_TOTAL_HI, SAB_I_OFFSET_HI, SAB_I_KILLED, SAB_I_ASYNC, SAB_I_STOP, U32, SAB_STATE_IDLE, SAB_STATE_PENDING, SAB_STATE_READY, SAB_STATUS_BYTES, SAB_STATUS_JSON, SAB_STATUS_VOID, SAB_STATUS_ERRNO, SAB_DEFAULT_WINDOW_BYTES, SAB_MIN_BYTES, SYNC_SAB_REQ_MSG, SYNC_SAB_NEXT_MSG, encoder, decoder2;
3582
- var init_sync_sab_wire = __esm({
3583
- "src/realm/sync-sab-wire.ts"() {
3584
- "use strict";
3585
- SAB_HEADER_I32 = 16;
3586
- SAB_CLOCK_OFFSET = SAB_HEADER_I32 * 4;
3587
- SAB_CLOCK_I64 = 3;
3588
- SAB_HEADER_BYTES = SAB_CLOCK_OFFSET + SAB_CLOCK_I64 * 8;
3589
- SAB_I_STATE = 0;
3590
- SAB_I_SEQ = 1;
3591
- SAB_I_STATUS = 2;
3592
- SAB_I_TOTAL = 3;
3593
- SAB_I_CHUNK = 4;
3594
- SAB_I_OFFSET = 5;
3595
- SAB_I_REQ = 6;
3596
- SAB_I_PUB = 7;
3597
- SAB_I_SIGNALS = 8;
3598
- SAB_I_TIMERS = 9;
3599
- SAB_I_MEMORY = 10;
3600
- SAB_I_TOTAL_HI = 11;
3601
- SAB_I_OFFSET_HI = 12;
3602
- SAB_I_KILLED = 13;
3603
- SAB_I_ASYNC = 14;
3604
- SAB_I_STOP = 15;
3605
- U32 = 2 ** 32;
3606
- SAB_STATE_IDLE = 0;
3607
- SAB_STATE_PENDING = 1;
3608
- SAB_STATE_READY = 2;
3609
- SAB_STATUS_BYTES = 1;
3610
- SAB_STATUS_JSON = 2;
3611
- SAB_STATUS_VOID = 3;
3612
- SAB_STATUS_ERRNO = 4;
3613
- SAB_DEFAULT_WINDOW_BYTES = 1024 * 1024;
3614
- SAB_MIN_BYTES = SAB_HEADER_BYTES + 4096;
3615
- SYNC_SAB_REQ_MSG = "sync-sab-req";
3616
- SYNC_SAB_NEXT_MSG = "sync-sab-next";
3617
- encoder = new TextEncoder();
3618
- decoder2 = new TextDecoder();
3619
- }
3620
- });
3621
-
3622
3675
  // src/process/js/async-sab.ts
3623
3676
  async function changed(header, index3, seen, waitAsync = defaultWaitAsync) {
3624
3677
  const waited = waitAsync(header, index3, seen);
@@ -4033,7 +4086,7 @@ function childOps(kernel, io, defaults) {
4033
4086
  const mine = [];
4034
4087
  const theirs = [];
4035
4088
  try {
4036
- const stdio = await slots(kernel, o, mine, theirs);
4089
+ const stdio = await slots2(kernel, o, mine, theirs);
4037
4090
  const pid = await kernel.json({
4038
4091
  op: "proc-spawn",
4039
4092
  file,
@@ -4078,7 +4131,7 @@ async function preflight(kernel, hows) {
4078
4131
  await kernel.json({ op: "fd-info", fd: how === "inherit" ? n : how });
4079
4132
  }
4080
4133
  }
4081
- async function slots(kernel, o, mine, theirs) {
4134
+ async function slots2(kernel, o, mine, theirs) {
4082
4135
  const hows = STDIO2.map((name2) => o[name2] ?? "inherit");
4083
4136
  await preflight(kernel, hows);
4084
4137
  const stdio = [];
@@ -5170,43 +5223,6 @@ var init_js_run = __esm({
5170
5223
  }
5171
5224
  });
5172
5225
 
5173
- // src/kernel/cpu-clock.ts
5174
- function epochMicros() {
5175
- return Math.floor((performance.timeOrigin + performance.now()) * 1e3);
5176
- }
5177
- function slots2(sab) {
5178
- return new BigInt64Array(sab, LOCAL, SAB_CLOCK_I64);
5179
- }
5180
- function useLocalClock(sab) {
5181
- local = sab && sab.byteLength >= LOCAL + SAB_CLOCK_I64 * 8 ? slots2(sab) : void 0;
5182
- if (!local) return;
5183
- const wait2 = (typed, index3, value2, timeout) => localWait(() => rawWait(typed, index3, value2, timeout));
5184
- Atomics.wait = wait2;
5185
- }
5186
- function localWait(wait2) {
5187
- const clock = local;
5188
- if (!clock) return wait2();
5189
- const start2 = BigInt(epochMicros());
5190
- const idle = Atomics.load(clock, IDLE);
5191
- Atomics.store(clock, IDLE, idle - start2);
5192
- try {
5193
- return wait2();
5194
- } finally {
5195
- const end = BigInt(epochMicros());
5196
- Atomics.store(clock, IDLE, idle + (end > start2 ? end - start2 : 0n));
5197
- }
5198
- }
5199
- var LOCAL, IDLE, local, rawWait;
5200
- var init_cpu_clock = __esm({
5201
- "src/kernel/cpu-clock.ts"() {
5202
- "use strict";
5203
- init_sync_sab_wire();
5204
- LOCAL = SAB_CLOCK_OFFSET;
5205
- IDLE = 1;
5206
- rawWait = Atomics.wait.bind(Atomics);
5207
- }
5208
- });
5209
-
5210
5226
  // src/realm/sync-sab-bridge.ts
5211
5227
  function syncCallCount() {
5212
5228
  return calls;
@@ -8701,7 +8717,10 @@ var init_process_fds = __esm({
8701
8717
  faccessat: "__syscall_faccessat",
8702
8718
  utimensat: "__syscall_utimensat",
8703
8719
  getppid: "slicc_getppid_js",
8704
- resizeHeap: "emscripten_resize_heap"
8720
+ resizeHeap: "emscripten_resize_heap",
8721
+ fdWrite: "fd_write",
8722
+ fdRead: "fd_read",
8723
+ sleepMs: "slicc_sleep_ms"
8705
8724
  };
8706
8725
  UTIME_NOW = 1073741823;
8707
8726
  UTIME_OMIT = 1073741822;
@@ -9541,8 +9560,8 @@ function pidStat(info, boot) {
9541
9560
  0,
9542
9561
  ticks(info.utime ?? 0),
9543
9562
  ticks(info.stime ?? 0),
9544
- 0,
9545
- 0,
9563
+ ticks(info.cutime ?? 0),
9564
+ ticks(info.cstime ?? 0),
9546
9565
  20,
9547
9566
  0,
9548
9567
  1,
@@ -9566,7 +9585,7 @@ function pidStat(info, boot) {
9566
9585
  `;
9567
9586
  }
9568
9587
  function pidStatus(info) {
9569
- const state = info.state === "Z" ? "Z (zombie)" : "S (sleeping)";
9588
+ const state = STATES[info.state];
9570
9589
  const c = info.cred ?? ROOT;
9571
9590
  const ids = (r, e, s) => `${r} ${e} ${s} ${e}`;
9572
9591
  return [
@@ -9842,7 +9861,7 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
9842
9861
  readdir: (node) => pidNames(selfReaddir ? selfReaddir(node) : [".", ".."])
9843
9862
  };
9844
9863
  }
9845
- var HZ, DIR_MODE2, FILE_MODE, LINK_MODE2, ENOENT, EINVAL, UID2, KIB, FALLBACK_MEMORY, PID_FILES, SYSTEM_FILES, sigMask;
9864
+ var HZ, DIR_MODE2, FILE_MODE, LINK_MODE2, ENOENT, EINVAL, UID2, KIB, FALLBACK_MEMORY, PID_FILES, SYSTEM_FILES, sigMask, STATES;
9846
9865
  var init_procfs = __esm({
9847
9866
  "src/process/procfs.ts"() {
9848
9867
  "use strict";
@@ -9860,6 +9879,7 @@ var init_procfs = __esm({
9860
9879
  PID_FILES = ["cmdline", "comm", "stat", "statm", "status"];
9861
9880
  SYSTEM_FILES = ["loadavg", "meminfo", "stat", "uptime"];
9862
9881
  sigMask = (mask = 0) => (mask >>> 1).toString(16).padStart(16, "0");
9882
+ STATES = { S: "S (sleeping)", T: "T (stopped)", Z: "Z (zombie)" };
9863
9883
  }
9864
9884
  });
9865
9885
 
@@ -10105,6 +10125,19 @@ function reportGrowth(imports, publish, glue) {
10105
10125
  return grown;
10106
10126
  });
10107
10127
  }
10128
+ function holdWhileStopped(imports, header, glue) {
10129
+ const hold = () => {
10130
+ while (Atomics.load(header, SAB_I_STOP) === 1) Atomics.wait(header, SAB_I_STOP, 1);
10131
+ };
10132
+ for (const name2 of ["fdWrite", "fdRead", "sleepMs"]) {
10133
+ wrapImport(imports, name2, glue, (original) => (...args) => {
10134
+ hold();
10135
+ const done = original(...args);
10136
+ hold();
10137
+ return done;
10138
+ });
10139
+ }
10140
+ }
10108
10141
  function callerOwner(Fs, init) {
10109
10142
  return init.owners ? {} : { owner: ownByCaller(Fs, init.cred, credAbi(init.program.glue)) };
10110
10143
  }
@@ -10129,6 +10162,7 @@ function kernelWrappers(imports, module, deps) {
10129
10162
  positionalIo(imports, { glue, fs: fsOf, sys, memory });
10130
10163
  const grown = () => publishMemory(init.sab, memory()?.buffer.byteLength ?? 0);
10131
10164
  reportGrowth(imports, grown, kernelGlue);
10165
+ holdWhileStopped(imports, new Int32Array(init.sab, 0, SAB_HEADER_I32), kernelGlue);
10132
10166
  }
10133
10167
  async function runWasmProcess(init, port3, deps = {}) {
10134
10168
  const signals = new SignalGate(
@@ -10420,6 +10454,9 @@ var init_process_runtime = __esm({
10420
10454
  " utimensat: typeof ___syscall_utimensat === 'function' ? ___syscall_utimensat : undefined,",
10421
10455
  " getppid: typeof _slicc_getppid_js === 'function' ? _slicc_getppid_js : undefined,",
10422
10456
  " resizeHeap: typeof _emscripten_resize_heap === 'function' ? _emscripten_resize_heap : undefined,",
10457
+ " fdWrite: typeof _fd_write === 'function' ? _fd_write : undefined,",
10458
+ " fdRead: typeof _fd_read === 'function' ? _fd_read : undefined,",
10459
+ " sleepMs: typeof slicc_sleep_ms === 'function' ? slicc_sleep_ms : undefined,",
10423
10460
  "};",
10424
10461
  "Module.sliccFdImports ??= {",
10425
10462
  " fd_sync: typeof _fd_sync === 'function' ? _fd_sync : undefined,",