@tileflow/react-native 0.1.0-alpha.1 → 0.1.0-alpha.2

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/index.js CHANGED
@@ -2,8 +2,8 @@ var __defProp = Object.defineProperty;
2
2
  var __typeError = (msg) => {
3
3
  throw TypeError(msg);
4
4
  };
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
6
+ var __publicField = (obj, key2, value) => __defNormalProp(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
7
7
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
8
8
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
9
9
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
@@ -53,11 +53,11 @@ function nativeInteractionDiagnostic(code) {
53
53
  message: messages[code]
54
54
  });
55
55
  }
56
- function nativeInteractionField(value, key) {
56
+ function nativeInteractionField(value, key2) {
57
57
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error();
58
58
  const prototype = Object.getPrototypeOf(value);
59
59
  if (prototype !== null && prototype !== Object.prototype) throw new Error();
60
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
60
+ const descriptor = Object.getOwnPropertyDescriptor(value, key2);
61
61
  if (!descriptor) return void 0;
62
62
  if (!("value" in descriptor) || !descriptor.enumerable) throw new Error();
63
63
  return descriptor.value;
@@ -92,18 +92,18 @@ function snapshotNativeInteractionJson(input) {
92
92
  if (keys2.length > length2 + 1) throw new Error();
93
93
  const result2 = new Array(length2);
94
94
  let sawLength = false;
95
- for (const key of keys2) {
96
- if (typeof key !== "string") throw new Error();
97
- if (key === "length") {
95
+ for (const key2 of keys2) {
96
+ if (typeof key2 !== "string") throw new Error();
97
+ if (key2 === "length") {
98
98
  sawLength = true;
99
99
  continue;
100
100
  }
101
- const index = Number(key);
102
- if (!Number.isSafeInteger(index) || index < 0 || index >= length2 || String(index) !== key)
101
+ const index = Number(key2);
102
+ if (!Number.isSafeInteger(index) || index < 0 || index >= length2 || String(index) !== key2)
103
103
  throw new Error();
104
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
104
+ const descriptor = Object.getOwnPropertyDescriptor(value, key2);
105
105
  if (!descriptor || !("value" in descriptor) || !descriptor.enumerable) throw new Error();
106
- Object.defineProperty(result2, key, {
106
+ Object.defineProperty(result2, key2, {
107
107
  value: copy(descriptor.value, depth + 1),
108
108
  enumerable: true,
109
109
  configurable: true,
@@ -118,12 +118,12 @@ function snapshotNativeInteractionJson(input) {
118
118
  throw new Error();
119
119
  properties2 += keys.length;
120
120
  const result = {};
121
- for (const key of keys) {
122
- if (typeof key !== "string" || key === "__proto__" || key === "prototype" || key === "constructor")
121
+ for (const key2 of keys) {
122
+ if (typeof key2 !== "string" || key2 === "__proto__" || key2 === "prototype" || key2 === "constructor")
123
123
  throw new Error();
124
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
124
+ const descriptor = Object.getOwnPropertyDescriptor(value, key2);
125
125
  if (!descriptor || !("value" in descriptor) || !descriptor.enumerable) throw new Error();
126
- result[key] = copy(descriptor.value, depth + 1);
126
+ result[key2] = copy(descriptor.value, depth + 1);
127
127
  }
128
128
  return Object.freeze(result);
129
129
  };
@@ -148,9 +148,9 @@ function nativeInteractionValuesEqual(left, right) {
148
148
  const a = Object.keys(left).sort();
149
149
  const b = Object.keys(right).sort();
150
150
  return a.length === b.length && a.every(
151
- (key, index) => key === b[index] && nativeInteractionValuesEqual(
152
- Object.getOwnPropertyDescriptor(left, key)?.value,
153
- Object.getOwnPropertyDescriptor(right, key)?.value
151
+ (key2, index) => key2 === b[index] && nativeInteractionValuesEqual(
152
+ Object.getOwnPropertyDescriptor(left, key2)?.value,
153
+ Object.getOwnPropertyDescriptor(right, key2)?.value
154
154
  )
155
155
  );
156
156
  }
@@ -267,8 +267,8 @@ function parseManifest(style) {
267
267
  if (priorityInput.length !== 4 || !priorityInput.every(representation) || new Set(priorityInput).size !== 4)
268
268
  throw new Error();
269
269
  const fieldsInput = nativeInteractionField(poi, "fields");
270
- const readField = (key) => {
271
- const value = nativeInteractionField(fieldsInput, key);
270
+ const readField = (key2) => {
271
+ const value = nativeInteractionField(fieldsInput, key2);
272
272
  if (!name(value)) throw new Error();
273
273
  return value;
274
274
  };
@@ -332,9 +332,9 @@ function featureId(value) {
332
332
  return typeof value === "string" && value.length > 0 && value.length <= tileflowInteractionLimits2.maxFeatureIdLength ? value : void 0;
333
333
  }
334
334
  function properties(input, fields) {
335
- const read = (key) => {
335
+ const read = (key2) => {
336
336
  try {
337
- return nativeInteractionField(input, fields[key]);
337
+ return nativeInteractionField(input, fields[key2]);
338
338
  } catch {
339
339
  return void 0;
340
340
  }
@@ -342,18 +342,18 @@ function properties(input, fields) {
342
342
  const result = {};
343
343
  const c = read("category");
344
344
  if (category(c)) result.category = c;
345
- for (const [key, output, max] of [
345
+ for (const [key2, output, max] of [
346
346
  ["filterRank", "filter_rank", 5],
347
347
  ["sizeRank", "size_rank", 16]
348
348
  ]) {
349
- const value = read(key);
349
+ const value = read(key2);
350
350
  if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && value <= max)
351
351
  result[output] = value;
352
352
  }
353
- for (const key of ["name", "type", "icon"]) {
354
- const value = read(key);
355
- if (typeof value === "string" && value.length <= tileflowInteractionLimits2.maxContentTextLength && (key === "name" || /^[a-z0-9]+(?:_[a-z0-9]+)*$/u.test(value)))
356
- result[key] = value;
353
+ for (const key2 of ["name", "type", "icon"]) {
354
+ const value = read(key2);
355
+ if (typeof value === "string" && value.length <= tileflowInteractionLimits2.maxContentTextLength && (key2 === "name" || /^[a-z0-9]+(?:_[a-z0-9]+)*$/u.test(value)))
356
+ result[key2] = value;
357
357
  }
358
358
  return Object.freeze(result);
359
359
  }
@@ -1098,9 +1098,9 @@ function createMountedMapInteractions(getStyle, changed) {
1098
1098
  if (disposed) return;
1099
1099
  const version = ++propsVersion;
1100
1100
  let invalidCallback = false;
1101
- const callback = (key) => {
1101
+ const callback = (key2) => {
1102
1102
  try {
1103
- const descriptor = Object.getOwnPropertyDescriptor(props, key);
1103
+ const descriptor = Object.getOwnPropertyDescriptor(props, key2);
1104
1104
  if (!descriptor) return void 0;
1105
1105
  if (!("value" in descriptor) || !descriptor.enumerable || descriptor.value !== void 0 && typeof descriptor.value !== "function")
1106
1106
  throw new Error();
@@ -1262,9 +1262,9 @@ function createMapLifecycle(create, retire) {
1262
1262
  if (refreshAgain && active && active !== epoch) refresh(active);
1263
1263
  }
1264
1264
  };
1265
- const forScene = (key) => {
1265
+ const forScene = (key2) => {
1266
1266
  const epoch = active;
1267
- return epoch?.owner.getSnapshot().renderer?.key === key ? epoch : void 0;
1267
+ return epoch?.owner.getSnapshot().renderer?.key === key2 ? epoch : void 0;
1268
1268
  };
1269
1269
  return Object.freeze({
1270
1270
  getSnapshot: () => snapshot,
@@ -1318,29 +1318,29 @@ function createMapLifecycle(create, retire) {
1318
1318
  unbindInteractionHost(host) {
1319
1319
  active?.interactions.unbind(host);
1320
1320
  },
1321
- beginTouch(key) {
1322
- forScene(key)?.interactions.beginTouch();
1321
+ beginTouch(key2) {
1322
+ forScene(key2)?.interactions.beginTouch();
1323
1323
  },
1324
- claimMarker(key, annotation) {
1325
- forScene(key)?.interactions.claimMarker(annotation);
1324
+ claimMarker(key2, annotation) {
1325
+ forScene(key2)?.interactions.claimMarker(annotation);
1326
1326
  },
1327
- markerPress(key, annotation) {
1328
- forScene(key)?.interactions.markerPress(annotation);
1327
+ markerPress(key2, annotation) {
1328
+ forScene(key2)?.interactions.markerPress(annotation);
1329
1329
  },
1330
- mapPress(key, input) {
1331
- void forScene(key)?.interactions.mapPress(input).catch(() => void 0);
1330
+ mapPress(key2, input) {
1331
+ void forScene(key2)?.interactions.mapPress(input).catch(() => void 0);
1332
1332
  },
1333
- interactionDiagnostic(key, code) {
1334
- forScene(key)?.interactions.report(code);
1333
+ interactionDiagnostic(key2, code) {
1334
+ forScene(key2)?.interactions.report(code);
1335
1335
  },
1336
- rootMounted(key, root) {
1337
- active?.owner.rootMounted(key, root);
1336
+ rootMounted(key2, root) {
1337
+ active?.owner.rootMounted(key2, root);
1338
1338
  },
1339
- nativeStyleLoaded(key, root) {
1340
- active?.owner.nativeStyleLoaded(key, root);
1339
+ nativeStyleLoaded(key2, root) {
1340
+ active?.owner.nativeStyleLoaded(key2, root);
1341
1341
  },
1342
- layoutChanged(key) {
1343
- active?.owner.layoutChanged(key);
1342
+ layoutChanged(key2) {
1343
+ active?.owner.layoutChanged(key2);
1344
1344
  },
1345
1345
  background() {
1346
1346
  active?.interactions.background();
@@ -1637,11 +1637,11 @@ function hasReservedNativeContext(url) {
1637
1637
  const query = url.indexOf("?");
1638
1638
  if (query < 0) return false;
1639
1639
  return url.slice(query + 1).split("&").some((part) => {
1640
- const key = part.split("=", 1)[0].replace(
1640
+ const key2 = part.split("=", 1)[0].replace(
1641
1641
  /%([0-9a-f]{2})/giu,
1642
1642
  (_, hex) => String.fromCharCode(Number.parseInt(hex, 16))
1643
1643
  );
1644
- return key.toLowerCase().startsWith("__tf_native");
1644
+ return key2.toLowerCase().startsWith("__tf_native");
1645
1645
  });
1646
1646
  }
1647
1647
  function nativeResourceOrigin(url) {
@@ -2341,7 +2341,7 @@ function normalizeBinding(value) {
2341
2341
  return Object.freeze({ kind: "direct" });
2342
2342
  }
2343
2343
  if (value.kind !== "hosted" || Object.keys(value).some(
2344
- (key) => !["kind", "apiOrigin", "credential", "mapId", "surfaceId"].includes(key)
2344
+ (key2) => !["kind", "apiOrigin", "credential", "mapId", "surfaceId"].includes(key2)
2345
2345
  ) || typeof value.credential !== "string" || !MOBILE_CREDENTIAL.test(value.credential) || typeof value.mapId !== "string" || !MAP_ID.test(value.mapId)) {
2346
2346
  throw new Error();
2347
2347
  }
@@ -2395,7 +2395,7 @@ function snapshotIdle(binding, session, lifecycle) {
2395
2395
  });
2396
2396
  }
2397
2397
  function parseSuccess(value, binding, expectedSessionId, expectedSurfaceId) {
2398
- if (!isRecord(value) || Object.keys(value).length !== SUCCESS_KEYS.size || Object.keys(value).some((key) => !SUCCESS_KEYS.has(key)) || value.ok !== true || value.kind !== "native" || value.version !== 1 || value.usageMode !== "session" || value.counted !== false || value.mapId !== binding.mapId || value.sessionId !== expectedSessionId || value.surfaceId !== expectedSurfaceId || typeof value.surfaceId !== "string" || !SURFACE_ID.test(value.surfaceId) || secretShaped(value.surfaceId) || typeof value.credentialId !== "string" || !CREDENTIAL_ID.test(value.credentialId) || !positiveRevision(value.credentialRevision) || !positiveRevision(value.deliveryPolicyRevision) || typeof value.grant !== "string" || value.grant.length === 0 || value.grant.length > GRANT_CHARACTER_LIMIT || !NATIVE_GRANT.test(value.grant) || !["disabled", "shadow", "enforced"].includes(String(value.meterMode)) || !["unmetered", "ordinary", "unbilled_fail_open"].includes(String(value.disposition)) || value.disposition === "unmetered" && value.meterMode !== "disabled") {
2398
+ if (!isRecord(value) || Object.keys(value).length !== SUCCESS_KEYS.size || Object.keys(value).some((key2) => !SUCCESS_KEYS.has(key2)) || value.ok !== true || value.kind !== "native" || value.version !== 1 || value.usageMode !== "session" || value.counted !== false || value.mapId !== binding.mapId || value.sessionId !== expectedSessionId || value.surfaceId !== expectedSurfaceId || typeof value.surfaceId !== "string" || !SURFACE_ID.test(value.surfaceId) || secretShaped(value.surfaceId) || typeof value.credentialId !== "string" || !CREDENTIAL_ID.test(value.credentialId) || !positiveRevision(value.credentialRevision) || !positiveRevision(value.deliveryPolicyRevision) || typeof value.grant !== "string" || value.grant.length === 0 || value.grant.length > GRANT_CHARACTER_LIMIT || !NATIVE_GRANT.test(value.grant) || !["disabled", "shadow", "enforced"].includes(String(value.meterMode)) || !["unmetered", "ordinary", "unbilled_fail_open"].includes(String(value.disposition)) || value.disposition === "unmetered" && value.meterMode !== "disabled") {
2399
2399
  throw new HostedNativeSessionError("NATIVE_SESSION_RESPONSE_INVALID");
2400
2400
  }
2401
2401
  const issuedAtMs = parseExactIso(value.issuedAt);
@@ -2493,7 +2493,7 @@ function positiveRevision(value) {
2493
2493
  return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
2494
2494
  }
2495
2495
  function isExactRestart(value, expectedSessionId) {
2496
- return isRecord(value) && Object.keys(value).length === RESTART_KEYS.size && Object.keys(value).every((key) => RESTART_KEYS.has(key)) && value.code === "COMMERCIAL_SESSION_RESTART_REQUIRED" && typeof value.error === "string" && value.error.length > 0 && value.error.length <= 500 && value.retryWithNewSession === true && value.sessionId === expectedSessionId;
2496
+ return isRecord(value) && Object.keys(value).length === RESTART_KEYS.size && Object.keys(value).every((key2) => RESTART_KEYS.has(key2)) && value.code === "COMMERCIAL_SESSION_RESTART_REQUIRED" && typeof value.error === "string" && value.error.length > 0 && value.error.length <= 500 && value.retryWithNewSession === true && value.sessionId === expectedSessionId;
2497
2497
  }
2498
2498
  async function readBoundedResponse(response, abort) {
2499
2499
  let reader;
@@ -3217,6 +3217,8 @@ function createAdmissionInstallation(create) {
3217
3217
  // src/mounted-map-owner.ts
3218
3218
  import {
3219
3219
  createTileflowNativeSourceController,
3220
+ nearestTileflowBlendTheme,
3221
+ planTileflowThemeBlend,
3220
3222
  resolveTileflowNativeManifestUrl as resolveTileflowNativeManifestUrl5
3221
3223
  } from "@tileflow/core/native";
3222
3224
 
@@ -3252,18 +3254,18 @@ function ownRecord(value, allowed2) {
3252
3254
  const keys = Reflect.ownKeys(value);
3253
3255
  if (keys.length > allowed2.length) return fail();
3254
3256
  const copy = /* @__PURE__ */ Object.create(null);
3255
- for (const key of keys) {
3256
- if (typeof key !== "string" || !allowed2.includes(key)) return fail();
3257
- const property = Object.getOwnPropertyDescriptor(value, key);
3257
+ for (const key2 of keys) {
3258
+ if (typeof key2 !== "string" || !allowed2.includes(key2)) return fail();
3259
+ const property = Object.getOwnPropertyDescriptor(value, key2);
3258
3260
  if (!property?.enumerable || !("value" in property)) return fail();
3259
- copy[key] = property.value;
3261
+ copy[key2] = property.value;
3260
3262
  }
3261
3263
  return copy;
3262
3264
  }
3263
3265
  function requireCompleteView(value) {
3264
3266
  if (!value || typeof value !== "object") return fail();
3265
- for (const key of ["center", "zoom", "bearing", "pitch"]) {
3266
- const property = Object.getOwnPropertyDescriptor(value, key);
3267
+ for (const key2 of ["center", "zoom", "bearing", "pitch"]) {
3268
+ const property = Object.getOwnPropertyDescriptor(value, key2);
3267
3269
  if (!property || !("value" in property) || property.value === void 0) return fail();
3268
3270
  }
3269
3271
  }
@@ -3351,11 +3353,11 @@ function configurationRecord(value) {
3351
3353
  const keys = Reflect.ownKeys(value);
3352
3354
  if (keys.length > 32) return invalid2();
3353
3355
  const result = /* @__PURE__ */ Object.create(null);
3354
- for (const key of keys) {
3355
- if (typeof key !== "string") return invalid2();
3356
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
3356
+ for (const key2 of keys) {
3357
+ if (typeof key2 !== "string") return invalid2();
3358
+ const descriptor = Object.getOwnPropertyDescriptor(value, key2);
3357
3359
  if (!descriptor || !("value" in descriptor)) return invalid2();
3358
- result[key] = descriptor.value;
3360
+ result[key2] = descriptor.value;
3359
3361
  }
3360
3362
  return result;
3361
3363
  }
@@ -3397,7 +3399,7 @@ function field(value, name3) {
3397
3399
  }
3398
3400
  function names(value, maximum2) {
3399
3401
  const keys = Reflect.ownKeys(record(value));
3400
- if (!keys.length || keys.length > maximum2 || keys.some((key) => typeof key !== "string"))
3402
+ if (!keys.length || keys.length > maximum2 || keys.some((key2) => typeof key2 !== "string"))
3401
3403
  throw new Error();
3402
3404
  return keys;
3403
3405
  }
@@ -3529,6 +3531,8 @@ var nativePreparationLimits = Object.freeze({
3529
3531
  tileJsonBytes: 1048576,
3530
3532
  depth: 64,
3531
3533
  nodes: 54e4,
3534
+ /** A blend style is planned locally from validated styles; split layers make it larger. */
3535
+ blendNodes: 216e4,
3532
3536
  sources: 128,
3533
3537
  layers: 4096,
3534
3538
  fontFaces: 16,
@@ -3611,11 +3615,11 @@ function nativeJsonBytes(value) {
3611
3615
  }
3612
3616
  return bytes;
3613
3617
  }
3614
- function freezeNativePreparedJson(value) {
3618
+ function freezeNativePreparedJson(value, maximumNodes = nativePreparationLimits.nodes) {
3615
3619
  let nodes = 0;
3616
3620
  const parents = /* @__PURE__ */ new Set();
3617
3621
  const visit = (input, depth) => {
3618
- if (++nodes > nativePreparationLimits.nodes || depth > nativePreparationLimits.depth)
3622
+ if (++nodes > maximumNodes || depth > nativePreparationLimits.depth)
3619
3623
  throw new NativePreparationError();
3620
3624
  if (input === null || typeof input === "boolean") return;
3621
3625
  if (typeof input === "number" && Number.isFinite(input)) return;
@@ -3626,17 +3630,17 @@ function freezeNativePreparedJson(value) {
3626
3630
  if (!array3 && Object.getPrototypeOf(input) !== Object.prototype && Object.getPrototypeOf(input) !== null)
3627
3631
  throw new NativePreparationError();
3628
3632
  const keys = Reflect.ownKeys(input);
3629
- if (array3 && (input.length > nativePreparationLimits.nodes || Object.keys(input).length !== input.length))
3633
+ if (array3 && (input.length > maximumNodes || Object.keys(input).length !== input.length))
3630
3634
  throw new NativePreparationError();
3631
3635
  parents.add(input);
3632
- for (const key of keys) {
3633
- if (array3 && key === "length") continue;
3634
- if (typeof key !== "string" || key === "__proto__" || key === "toJSON")
3636
+ for (const key2 of keys) {
3637
+ if (array3 && key2 === "length") continue;
3638
+ if (typeof key2 !== "string" || key2 === "__proto__" || key2 === "toJSON")
3635
3639
  throw new NativePreparationError();
3636
- const property = Object.getOwnPropertyDescriptor(input, key);
3640
+ const property = Object.getOwnPropertyDescriptor(input, key2);
3637
3641
  if (!property || !property.enumerable || !("value" in property))
3638
3642
  throw new NativePreparationError();
3639
- visit(key, depth + 1);
3643
+ visit(key2, depth + 1);
3640
3644
  visit(property.value, depth + 1);
3641
3645
  }
3642
3646
  parents.delete(input);
@@ -3822,13 +3826,13 @@ function snapshotNativeMapOptions(value) {
3822
3826
  const keys = Reflect.ownKeys(value);
3823
3827
  if (keys.length > allowed.size) throw new Error();
3824
3828
  const result = {};
3825
- for (const key of keys) {
3826
- if (typeof key !== "string" || !allowed.has(key)) throw new Error();
3827
- const property = Object.getOwnPropertyDescriptor(value, key);
3829
+ for (const key2 of keys) {
3830
+ if (typeof key2 !== "string" || !allowed.has(key2)) throw new Error();
3831
+ const property = Object.getOwnPropertyDescriptor(value, key2);
3828
3832
  if (!property || !property.enumerable || !("value" in property)) throw new Error();
3829
3833
  if (property.value === void 0) continue;
3830
3834
  if (typeof property.value !== "boolean") throw new Error();
3831
- result[key] = property.value;
3835
+ result[key2] = property.value;
3832
3836
  }
3833
3837
  return Object.freeze(result);
3834
3838
  } catch {
@@ -3893,10 +3897,10 @@ function createMapCameraController(port, onError = () => void 0) {
3893
3897
  }
3894
3898
  function failed(run) {
3895
3899
  if (!current(run)) return;
3896
- const own2 = revision;
3900
+ const own3 = revision;
3897
3901
  pending = void 0;
3898
3902
  retire(run);
3899
- if (disposed || revision !== own2) return;
3903
+ if (disposed || revision !== own3) return;
3900
3904
  try {
3901
3905
  void Promise.resolve(report?.(new CameraControllerError("CAMERA_COMMAND_FAILED"))).catch(
3902
3906
  () => void 0
@@ -3947,9 +3951,9 @@ function createMapCameraController(port, onError = () => void 0) {
3947
3951
  function update(input) {
3948
3952
  assertUsable();
3949
3953
  if (!mounted) throw new CameraControllerError("CAMERA_NOT_MOUNTED");
3950
- const own2 = advance();
3954
+ const own3 = advance();
3951
3955
  const next = snapshotCameraProps(input);
3952
- if (disposed || revision !== own2) return;
3956
+ if (disposed || revision !== own3) return;
3953
3957
  if (next.mode !== mode) throw new CameraControllerError("CAMERA_MODE_CHANGE");
3954
3958
  props = next;
3955
3959
  reconcile();
@@ -3960,9 +3964,9 @@ function createMapCameraController(port, onError = () => void 0) {
3960
3964
  update(input);
3961
3965
  return;
3962
3966
  }
3963
- const own2 = advance();
3967
+ const own3 = advance();
3964
3968
  const next = snapshotCameraProps(input, fallbacks);
3965
- if (disposed || revision !== own2) return;
3969
+ if (disposed || revision !== own3) return;
3966
3970
  mode = next.mode;
3967
3971
  props = next;
3968
3972
  live = next.view;
@@ -3994,9 +3998,9 @@ function createMapCameraController(port, onError = () => void 0) {
3994
3998
  changeGesture(identity, input) {
3995
3999
  const active = gesture;
3996
4000
  if (disposed || !active || active.token !== identity) return;
3997
- const own2 = advance();
4001
+ const own3 = advance();
3998
4002
  const view = snapshotCameraView(input);
3999
- if (disposed || gesture !== active || revision !== own2) return;
4003
+ if (disposed || gesture !== active || revision !== own3) return;
4000
4004
  live = view;
4001
4005
  if (sameCameraView(active.lastEmitted, view)) return;
4002
4006
  active.lastEmitted = view;
@@ -4005,9 +4009,9 @@ function createMapCameraController(port, onError = () => void 0) {
4005
4009
  endGesture(identity, input) {
4006
4010
  const active = gesture;
4007
4011
  if (disposed || !active || active.token !== identity) return;
4008
- const own2 = advance();
4012
+ const own3 = advance();
4009
4013
  const view = snapshotCameraView(input);
4010
- if (disposed || gesture !== active || revision !== own2) return;
4014
+ if (disposed || gesture !== active || revision !== own3) return;
4011
4015
  live = view;
4012
4016
  gesture = void 0;
4013
4017
  const waiting = { token: identity, notifying: true };
@@ -4042,9 +4046,9 @@ function createMapCameraController(port, onError = () => void 0) {
4042
4046
  observeCommand(identity, input) {
4043
4047
  const run = pending;
4044
4048
  if (!run || !current(run) || run.command.token !== identity) return;
4045
- const own2 = advance();
4049
+ const own3 = advance();
4046
4050
  const view = snapshotCameraView(input);
4047
- if (!current(run) || revision !== own2) return;
4051
+ if (!current(run) || revision !== own3) return;
4048
4052
  live = view;
4049
4053
  },
4050
4054
  /** Called explicitly by the renderer owner after replacing style/source on this instance. */
@@ -4177,13 +4181,13 @@ function createNativeInteractionStyleOwner(changed) {
4177
4181
  get() {
4178
4182
  return proof?.isCurrent() ? proof : void 0;
4179
4183
  },
4180
- publish(key, token, style, current) {
4184
+ publish(key2, token, style, current) {
4181
4185
  revoke?.();
4182
4186
  let live = true;
4183
4187
  revoke = () => {
4184
4188
  live = false;
4185
4189
  };
4186
- proof = Object.freeze({ key, token, style, isCurrent: () => live && current() });
4190
+ proof = Object.freeze({ key: key2, token, style, isCurrent: () => live && current() });
4187
4191
  notify();
4188
4192
  },
4189
4193
  retire() {
@@ -4266,6 +4270,160 @@ function createNativeReadiness(notify) {
4266
4270
  });
4267
4271
  }
4268
4272
 
4273
+ // src/native-theme-blend.ts
4274
+ import {
4275
+ fillTileflowThemeBlendTemplate
4276
+ } from "@tileflow/core/native";
4277
+ var nativeBlendLabelFadeMs = 450;
4278
+ var minimumStep = 25e-4;
4279
+ var imageSteps = 32;
4280
+ function createNativeThemeBlender(plan, port, options) {
4281
+ const clamp = (value) => Math.min(plan.themes - 1, Math.max(0, Number.isFinite(value) ? value : 0));
4282
+ const ground = plan.paints.filter((paint) => paint.follows === "position");
4283
+ const symbols = plan.paints.filter((paint) => paint.follows === "dominant");
4284
+ const patterns = plan.images.filter((image) => image.follows === "position");
4285
+ const shownPaints = /* @__PURE__ */ new Map();
4286
+ const shownSwitches = /* @__PURE__ */ new Map();
4287
+ const shownImages = /* @__PURE__ */ new Map();
4288
+ let shownLight;
4289
+ const baked = clamp(options.baked);
4290
+ let position = baked;
4291
+ let dominant = Math.round(baked);
4292
+ let target = baked;
4293
+ let stepped = baked;
4294
+ let scheduled = false;
4295
+ let disposed = false;
4296
+ let queue = Promise.resolve();
4297
+ for (const paint of ground)
4298
+ shownPaints.set(paint, key(fillTileflowThemeBlendTemplate(paint.template, baked)));
4299
+ for (const paint of symbols)
4300
+ shownPaints.set(paint, key(fillTileflowThemeBlendTemplate(paint.template, dominant)));
4301
+ for (const entry of plan.switches) shownSwitches.set(entry, key(entry.values[dominant] ?? null));
4302
+ for (const image of patterns) shownImages.set(image, imageKey(image, baked));
4303
+ if (plan.light !== void 0) shownLight = key(fillTileflowThemeBlendTemplate(plan.light, baked));
4304
+ function groundValues(at) {
4305
+ const paint = [];
4306
+ for (const entry of ground) {
4307
+ const value = fillTileflowThemeBlendTemplate(entry.template, at);
4308
+ const shown = key(value);
4309
+ if (shownPaints.get(entry) === shown) continue;
4310
+ shownPaints.set(entry, shown);
4311
+ paint.push([entry.layer, entry.property, value]);
4312
+ }
4313
+ const images = [];
4314
+ for (const image of patterns) {
4315
+ const shown = imageKey(image, at);
4316
+ if (shownImages.get(image) === shown) continue;
4317
+ shownImages.set(image, shown);
4318
+ const [index, t] = imageMix(image, at);
4319
+ images.push([image.names[0], image.names[index], image.names[index + 1], t]);
4320
+ }
4321
+ let light2;
4322
+ if (plan.light !== void 0) {
4323
+ const value = fillTileflowThemeBlendTemplate(plan.light, at);
4324
+ const shown = key(value);
4325
+ if (shown !== shownLight) {
4326
+ shownLight = shown;
4327
+ light2 = value;
4328
+ }
4329
+ }
4330
+ if (!paint.length && !images.length && light2 === void 0) return void 0;
4331
+ return { paint, images, ...light2 === void 0 ? {} : { light: light2 } };
4332
+ }
4333
+ function nearestValues(theme) {
4334
+ const paint = [];
4335
+ const layout = [];
4336
+ for (const entry of symbols) {
4337
+ const value = fillTileflowThemeBlendTemplate(entry.template, theme);
4338
+ const shown = key(value);
4339
+ if (shownPaints.get(entry) === shown) continue;
4340
+ shownPaints.set(entry, shown);
4341
+ paint.push([entry.layer, entry.property, value]);
4342
+ }
4343
+ for (const entry of plan.switches) {
4344
+ const value = entry.values[theme] ?? null;
4345
+ const shown = key(value);
4346
+ if (shownSwitches.get(entry) === shown) continue;
4347
+ shownSwitches.set(entry, shown);
4348
+ (entry.group === "paint" ? paint : layout).push([entry.layer, entry.property, value]);
4349
+ }
4350
+ if (!paint.length && !layout.length) return void 0;
4351
+ return { paint, layout };
4352
+ }
4353
+ async function step() {
4354
+ scheduled = false;
4355
+ if (disposed) return;
4356
+ const goal = target;
4357
+ stepped = goal;
4358
+ const reachesTheme = goal % 1 === 0 && goal !== position;
4359
+ if (Math.abs(goal - position) >= minimumStep || reachesTheme) {
4360
+ position = goal;
4361
+ const values = groundValues(position);
4362
+ if (values) await port.apply(values);
4363
+ }
4364
+ const nearest = Math.round(goal);
4365
+ if (nearest !== dominant && !disposed) {
4366
+ dominant = nearest;
4367
+ const values = nearestValues(nearest);
4368
+ if (values) {
4369
+ const covered = await port.cover(nativeBlendLabelFadeMs).catch(() => false);
4370
+ if (disposed) return;
4371
+ await port.apply(values);
4372
+ if (covered) void port.reveal(nativeBlendLabelFadeMs).catch(() => void 0);
4373
+ }
4374
+ }
4375
+ }
4376
+ function schedule() {
4377
+ if (scheduled || disposed) return;
4378
+ scheduled = true;
4379
+ queue = queue.then(step).then(
4380
+ () => {
4381
+ if (!disposed && target !== stepped) schedule();
4382
+ },
4383
+ () => {
4384
+ if (disposed) return;
4385
+ disposed = true;
4386
+ options.failed();
4387
+ }
4388
+ );
4389
+ }
4390
+ return Object.freeze({
4391
+ get position() {
4392
+ return position;
4393
+ },
4394
+ get dominant() {
4395
+ return dominant;
4396
+ },
4397
+ set(next) {
4398
+ if (disposed) return;
4399
+ target = clamp(next);
4400
+ schedule();
4401
+ },
4402
+ /** Resolves once every scheduled batch has been sent. */
4403
+ async whenIdle() {
4404
+ for (; ; ) {
4405
+ const pending = queue;
4406
+ await pending;
4407
+ if (pending === queue && !scheduled) return;
4408
+ }
4409
+ },
4410
+ dispose() {
4411
+ disposed = true;
4412
+ }
4413
+ });
4414
+ }
4415
+ function key(value) {
4416
+ return JSON.stringify(value) ?? "undefined";
4417
+ }
4418
+ function imageMix(image, at) {
4419
+ const quantized = Math.round(at * imageSteps) / imageSteps;
4420
+ const index = Math.min(image.names.length - 2, Math.max(0, Math.floor(quantized)));
4421
+ return [index, Math.min(1, Math.max(0, quantized - index))];
4422
+ }
4423
+ function imageKey(image, at) {
4424
+ return imageMix(image, at).join(":");
4425
+ }
4426
+
4269
4427
  // src/native-renderer-owner.ts
4270
4428
  var blank = Object.freeze({ version: 8, sources: Object.freeze({}), layers: Object.freeze([]) });
4271
4429
  var selection = (target) => Object.freeze({
@@ -4275,7 +4433,7 @@ var selection = (target) => Object.freeze({
4275
4433
  colorScheme: target.source.theme.colorScheme
4276
4434
  })
4277
4435
  });
4278
- function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4436
+ function createNativeRendererOwner(key2, initialTarget, initialCamera, ports2) {
4279
4437
  let disposed = false;
4280
4438
  let terminal = false;
4281
4439
  let foreground = true;
@@ -4302,10 +4460,17 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4302
4460
  let gesture;
4303
4461
  let settlement;
4304
4462
  let cameraProps = initialCamera;
4463
+ let transitionMs = 0;
4464
+ let drawn = false;
4465
+ let covering = false;
4466
+ let coverMs = 0;
4467
+ let revealing;
4468
+ let blender;
4469
+ let blendPosition;
4305
4470
  const initial = snapshotCameraProps(initialCamera, { manifestView: initialTarget.source.map.view });
4306
4471
  const initialView = initial.view;
4307
4472
  let snapshot = Object.freeze({
4308
- key,
4473
+ key: key2,
4309
4474
  style: blank,
4310
4475
  initialView,
4311
4476
  revision
@@ -4336,6 +4501,38 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4336
4501
  }
4337
4502
  };
4338
4503
  const readiness = createNativeReadiness((status) => {
4504
+ if (disposed) return;
4505
+ if (status === "ready" && covering) reveal();
4506
+ else publishReadiness(status);
4507
+ });
4508
+ function reveal() {
4509
+ const version = transaction;
4510
+ const nativeSurface = surface;
4511
+ if (revealing?.version === version) return;
4512
+ if (!nativeSurface?.reveal) {
4513
+ covering = false;
4514
+ if (readiness.ready) publishReadiness("ready");
4515
+ return;
4516
+ }
4517
+ const work = nativeSurface.reveal(coverMs).catch(() => nativeSurface.discardCover?.()).catch(() => void 0);
4518
+ revealing = { version, work };
4519
+ track(
4520
+ work.then(() => {
4521
+ if (revealing?.work === work) revealing = void 0;
4522
+ if (disposed || version !== transaction) return;
4523
+ covering = false;
4524
+ if (readiness.ready) publishReadiness("ready");
4525
+ })
4526
+ );
4527
+ }
4528
+ function discardCover() {
4529
+ if (!covering) return;
4530
+ covering = false;
4531
+ revealing = void 0;
4532
+ const nativeSurface = surface;
4533
+ if (nativeSurface?.discardCover) track(nativeSurface.discardCover().catch(() => void 0));
4534
+ }
4535
+ function publishReadiness(status) {
4339
4536
  if (disposed) return;
4340
4537
  const version = transaction;
4341
4538
  if (status === "ready" && pendingSuccess && !rollback) {
@@ -4352,11 +4549,12 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4352
4549
  });
4353
4550
  }
4354
4551
  } else emit({ type: "readiness-change", generation: eventGeneration, status });
4355
- });
4552
+ }
4356
4553
  const cameraPort = createNativeCameraPort({
4357
4554
  applyCamera(command, view) {
4358
- if (!surface || disposed || terminal || !loaded || !foreground)
4555
+ if (!surface || disposed || terminal || !foreground)
4359
4556
  return Promise.reject(new NativePreparationError());
4557
+ if (!loaded) return Promise.resolve(Object.freeze({ command, view }));
4360
4558
  return surface.applyCamera(command, view);
4361
4559
  },
4362
4560
  cancelCamera(command) {
@@ -4374,7 +4572,7 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4374
4572
  const expected = token;
4375
4573
  const generation = eventGeneration;
4376
4574
  interactionStyles.publish(
4377
- key,
4575
+ key2,
4378
4576
  expected,
4379
4577
  style,
4380
4578
  () => !disposed && !terminal && foreground && !preloading && styleAccepted && loaded && surface === nativeSurface && token === expected && snapshot.style === style && transaction === version && eventGeneration === generation
@@ -4397,6 +4595,9 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4397
4595
  if (disposed || terminal || !foreground || !styleAccepted || loaded || version !== transaction)
4398
4596
  return;
4399
4597
  loaded = true;
4598
+ drawn = true;
4599
+ if (covering) reveal();
4600
+ startBlender(version);
4400
4601
  publishInteractionStyle(version);
4401
4602
  if (disposed || version !== transaction || !foreground) return;
4402
4603
  emit({ type: "load", generation: eventGeneration, selection: selection(active) });
@@ -4418,8 +4619,45 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4418
4619
  fail2();
4419
4620
  }
4420
4621
  }
4622
+ function stopBlender() {
4623
+ blender?.dispose();
4624
+ blender = void 0;
4625
+ }
4626
+ function startBlender(version) {
4627
+ const blend = active.blend;
4628
+ const nativeSurface = surface;
4629
+ if (!blend || blender || !nativeSurface?.applyThemeValues || version !== transaction) return;
4630
+ const style = token;
4631
+ const owned2 = () => !disposed && !terminal && version === transaction && surface === nativeSurface;
4632
+ blender = createNativeThemeBlender(
4633
+ blend.plan,
4634
+ {
4635
+ apply(values) {
4636
+ if (!owned2()) return Promise.resolve();
4637
+ return nativeSurface.applyThemeValues(style, values);
4638
+ },
4639
+ cover(duration) {
4640
+ if (!owned2() || !foreground || !nativeSurface.cover) return Promise.resolve(false);
4641
+ return nativeSurface.cover(duration);
4642
+ },
4643
+ reveal(duration) {
4644
+ if (!nativeSurface.reveal) return Promise.resolve();
4645
+ return nativeSurface.reveal(duration);
4646
+ }
4647
+ },
4648
+ {
4649
+ baked: blend.position,
4650
+ failed() {
4651
+ if (owned2()) fail2();
4652
+ }
4653
+ }
4654
+ );
4655
+ if (blendPosition !== void 0) blender.set(blendPosition);
4656
+ }
4421
4657
  function apply(target, restoring) {
4422
4658
  if (disposed) return;
4659
+ stopBlender();
4660
+ blendPosition = target.blend?.position;
4423
4661
  const version = ++transaction;
4424
4662
  if (styleSequence >= Number.MAX_SAFE_INTEGER) {
4425
4663
  terminal = true;
@@ -4444,8 +4682,17 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4444
4682
  readiness.begin(expected);
4445
4683
  if (!surface) return;
4446
4684
  const nativeSurface = surface;
4685
+ const duration = restoring || !drawn || !foreground ? 0 : transitionMs;
4447
4686
  const work = Promise.resolve().then(async () => {
4448
4687
  if (disposed || version !== transaction) return;
4688
+ if (duration > 0 && nativeSurface.cover) {
4689
+ const covered = await nativeSurface.cover(duration).catch(() => false);
4690
+ if (covered && !disposed) {
4691
+ covering = true;
4692
+ coverMs = duration;
4693
+ }
4694
+ if (disposed || version !== transaction || surface !== nativeSurface) return;
4695
+ }
4449
4696
  await nativeSurface.expectStyle(expected);
4450
4697
  if (disposed || version !== transaction || surface !== nativeSurface) return;
4451
4698
  const layers = target.style.layers;
@@ -4453,21 +4700,24 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4453
4700
  (layer) => !layer || typeof layer !== "object" || typeof layer.id !== "string" || layer.id.startsWith("__tileflow_native_style_")
4454
4701
  ))
4455
4702
  throw new NativePreparationError();
4456
- const style = freezeNativePreparedJson({
4457
- ...target.style,
4458
- layers: [
4459
- ...layers,
4460
- {
4461
- id: `__tileflow_native_style_${expected}`,
4462
- type: "background",
4463
- paint: {
4464
- "background-color": "rgba(0,0,0,0)",
4465
- "background-opacity": 1
4703
+ const style = freezeNativePreparedJson(
4704
+ {
4705
+ ...target.style,
4706
+ layers: [
4707
+ ...layers,
4708
+ {
4709
+ id: `__tileflow_native_style_${expected}`,
4710
+ type: "background",
4711
+ paint: {
4712
+ "background-color": "rgba(0,0,0,0)",
4713
+ "background-opacity": 1
4714
+ }
4466
4715
  }
4467
- }
4468
- ]
4469
- });
4470
- snapshot = Object.freeze({ key, style, initialView, revision: ++revision });
4716
+ ]
4717
+ },
4718
+ target.blend ? nativePreparationLimits.blendNodes : nativePreparationLimits.nodes
4719
+ );
4720
+ snapshot = Object.freeze({ key: key2, style, initialView, revision: ++revision });
4471
4721
  if (!restoring)
4472
4722
  emit({
4473
4723
  type: "theme-change",
@@ -4489,6 +4739,8 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4489
4739
  const previous = committed;
4490
4740
  const version = transaction;
4491
4741
  interactionStyles.retire();
4742
+ discardCover();
4743
+ stopBlender();
4492
4744
  if (disposed || version !== transaction) return;
4493
4745
  emit({ type: "renderer-error", generation });
4494
4746
  if (disposed || version !== transaction) return;
@@ -4574,6 +4826,20 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4574
4826
  get currentTarget() {
4575
4827
  return committed;
4576
4828
  },
4829
+ /** The latest target applied, which may still be loading. */
4830
+ get activeTarget() {
4831
+ return terminal ? void 0 : active;
4832
+ },
4833
+ /** Moves a blend target to another position; ignored while no blend is shown. */
4834
+ setBlendPosition(position) {
4835
+ if (disposed || !Number.isFinite(position)) return;
4836
+ blendPosition = position;
4837
+ if (active.blend) blender?.set(position);
4838
+ },
4839
+ /** Cross-fade length for later style replacements, in milliseconds; 0 changes at once. */
4840
+ setTransition(duration) {
4841
+ transitionMs = Number.isSafeInteger(duration) && duration > 0 && duration <= 5e3 ? duration : 0;
4842
+ },
4577
4843
  bindRoot(rootTag) {
4578
4844
  if (disposed || !Number.isSafeInteger(rootTag) || rootTag < 1 || root !== void 0 && root !== rootTag)
4579
4845
  return;
@@ -4629,7 +4895,16 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4629
4895
  apply(target, false);
4630
4896
  },
4631
4897
  reuseTarget(source) {
4632
- if (disposed || !committed || terminal) return;
4898
+ if (disposed || terminal) return;
4899
+ if (active !== committed || !committed) {
4900
+ active = { ...active, source };
4901
+ eventGeneration = source.generation;
4902
+ preloading = false;
4903
+ interruptCamera();
4904
+ invalidate();
4905
+ publishInteractionStyle(transaction);
4906
+ return;
4907
+ }
4633
4908
  active = { ...committed, source };
4634
4909
  committed = active;
4635
4910
  const target = active;
@@ -4751,6 +5026,7 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4751
5026
  async whenIdle() {
4752
5027
  for (; ; ) {
4753
5028
  await cameraPort.whenIdle();
5029
+ await blender?.whenIdle();
4754
5030
  if (!tasks.size) return;
4755
5031
  await Promise.allSettled([...tasks]);
4756
5032
  }
@@ -4760,6 +5036,7 @@ function createNativeRendererOwner(key, initialTarget, initialCamera, ports2) {
4760
5036
  disposed = true;
4761
5037
  ++transaction;
4762
5038
  ++barrierEpoch;
5039
+ stopBlender();
4763
5040
  interactionStyles.retire();
4764
5041
  readiness.dispose();
4765
5042
  camera.dispose();
@@ -4950,9 +5227,9 @@ function fontMetadata(input, developmentOrigin) {
4950
5227
  if (!record2(value)) throw invalid3();
4951
5228
  const keys = Reflect.ownKeys(value);
4952
5229
  if (keys.some(
4953
- (key) => typeof key !== "string" || !["id", "family", "url", "source", "format", "style", "weight"].includes(key)
4954
- ) || keys.some((key) => {
4955
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
5230
+ (key2) => typeof key2 !== "string" || !["id", "family", "url", "source", "format", "style", "weight"].includes(key2)
5231
+ ) || keys.some((key2) => {
5232
+ const descriptor = Object.getOwnPropertyDescriptor(value, key2);
4956
5233
  return !descriptor?.enumerable || !("value" in descriptor);
4957
5234
  }))
4958
5235
  throw invalid3();
@@ -4991,7 +5268,7 @@ function validateFontFaces(faces, documentUrl, metadata, add, rewrites, policy,
4991
5268
  for (const definition of definitions) {
4992
5269
  if (++count > nativePreparationLimits.fontFaces || !record2(definition)) throw invalid3();
4993
5270
  const keys = Object.keys(definition).sort();
4994
- if (keys.length !== 4 || !["font-family", "font-style", "font-weight", "url"].every((key) => keys.includes(key)))
5271
+ if (keys.length !== 4 || !["font-family", "font-style", "font-weight", "url"].every((key2) => keys.includes(key2)))
4995
5272
  throw invalid3();
4996
5273
  if (typeof definition["font-family"] !== "string" || !fontStyles.has(String(definition["font-style"])) || typeof definition["font-weight"] !== "number" || !Number.isInteger(definition["font-weight"]) || !fontWeights.has(String(definition["font-weight"])))
4997
5274
  throw invalid3();
@@ -5064,7 +5341,7 @@ async function projectNativeResources(ports2) {
5064
5341
  const styleUrl = resolveUrl(ports2.styleUrl, ports2.styleUrl);
5065
5342
  const document = await read(styleUrl, "style");
5066
5343
  const style = JSON.parse(JSON.stringify(document.value));
5067
- if (style.version !== 8 || !record2(style.sources) || !Array.isArray(style.layers) || Object.keys(style).some((key) => !roots.has(key)) || Object.keys(style.sources).length > nativePreparationLimits.sources || style.layers.length > nativePreparationLimits.layers)
5344
+ if (style.version !== 8 || !record2(style.sources) || !Array.isArray(style.layers) || Object.keys(style).some((key2) => !roots.has(key2)) || Object.keys(style.sources).length > nativePreparationLimits.sources || style.layers.length > nativePreparationLimits.layers)
5068
5345
  throw invalid3();
5069
5346
  const rewrites = [];
5070
5347
  for (const sourceId of Object.keys(style.sources).sort()) {
@@ -5080,9 +5357,9 @@ async function projectNativeResources(ports2) {
5080
5357
  throw invalid3();
5081
5358
  declaringUrl = tileJson.url;
5082
5359
  delete source.url;
5083
- for (const key of ["tiles", "bounds", "minzoom", "maxzoom", "scheme", "attribution"]) {
5084
- if (source[key] === void 0 && tileJson.value[key] !== void 0)
5085
- source[key] = JSON.parse(JSON.stringify(tileJson.value[key]));
5360
+ for (const key2 of ["tiles", "bounds", "minzoom", "maxzoom", "scheme", "attribution"]) {
5361
+ if (source[key2] === void 0 && tileJson.value[key2] !== void 0)
5362
+ source[key2] = JSON.parse(JSON.stringify(tileJson.value[key2]));
5086
5363
  }
5087
5364
  }
5088
5365
  if (!Array.isArray(source.tiles) || source.tiles.length < 1 || source.tiles.length > 16)
@@ -5188,14 +5465,72 @@ function projectMapSourceState(state) {
5188
5465
  });
5189
5466
  }
5190
5467
 
5468
+ // src/theme-motion-input.ts
5469
+ import { validateTileflowThemeBlendSelection } from "@tileflow/core/native";
5470
+ var maximumTransitionMs = 5e3;
5471
+ function own(value, keys) {
5472
+ const prototype = Object.getPrototypeOf(value);
5473
+ if (Array.isArray(value) || prototype !== Object.prototype && prototype !== null)
5474
+ throw new NativePreparationError();
5475
+ const result = {};
5476
+ for (const key2 of Reflect.ownKeys(value)) {
5477
+ if (typeof key2 !== "string" || !keys.includes(key2)) throw new NativePreparationError();
5478
+ const property = Object.getOwnPropertyDescriptor(value, key2);
5479
+ if (!property || !("value" in property)) throw new NativePreparationError();
5480
+ result[key2] = property.value;
5481
+ }
5482
+ return result;
5483
+ }
5484
+ function snapshotThemeTransition(value) {
5485
+ if (value === void 0) return 0;
5486
+ if (!value || typeof value !== "object") throw new NativePreparationError();
5487
+ const { duration = 0 } = own(value, ["duration"]);
5488
+ if (typeof duration !== "number" || !Number.isFinite(duration) || duration < 0 || duration > maximumTransitionMs)
5489
+ throw new NativePreparationError();
5490
+ return Math.round(duration);
5491
+ }
5492
+ function snapshotThemeBlend(value) {
5493
+ if (value === void 0) return void 0;
5494
+ if (!value || typeof value !== "object") throw new NativePreparationError();
5495
+ const { themes, position } = own(value, ["themes", "position"]);
5496
+ if (!Array.isArray(themes)) throw new NativePreparationError();
5497
+ const blend = { themes: Object.freeze([...themes]), position };
5498
+ if (!validateTileflowThemeBlendSelection(blend)) throw new NativePreparationError();
5499
+ return Object.freeze(blend);
5500
+ }
5501
+ function themeBlendKey(blend) {
5502
+ return JSON.stringify(blend.themes);
5503
+ }
5504
+
5191
5505
  // src/mounted-map-owner.ts
5506
+ function themeSource(source, name3) {
5507
+ const theme = Object.hasOwn(source.map.themes, name3) ? source.map.themes[name3] : void 0;
5508
+ if (!theme) throw new NativePreparationError();
5509
+ return { ...source, theme: { ...theme, name: name3 } };
5510
+ }
5511
+ function themeIdentity(source) {
5512
+ return JSON.stringify([source.theme.name, source.theme.styleUrl, source.theme.revision ?? null]);
5513
+ }
5514
+ function heldStyle(targets, source) {
5515
+ const identity = themeIdentity(source);
5516
+ for (const target of targets) {
5517
+ if (!target) continue;
5518
+ if (!target.blend && themeIdentity(target.source) === identity) return target.style;
5519
+ const held = target.blend?.styles.get(identity);
5520
+ if (held) return held;
5521
+ }
5522
+ return void 0;
5523
+ }
5524
+ function sameTheme(shown, source) {
5525
+ return shown.theme.name === source.theme.name && shown.theme.styleUrl === source.theme.styleUrl && shown.theme.revision === source.theme.revision;
5526
+ }
5192
5527
  function cameraInput(props) {
5193
5528
  const result = {};
5194
- for (const key of ["view", "initialView", "onViewChange"]) {
5195
- const property = Object.getOwnPropertyDescriptor(props, key);
5529
+ for (const key2 of ["view", "initialView", "onViewChange"]) {
5530
+ const property = Object.getOwnPropertyDescriptor(props, key2);
5196
5531
  if (!property) continue;
5197
5532
  if (!("value" in property)) throw new NativePreparationError();
5198
- result[key] = property.value;
5533
+ result[key2] = property.value;
5199
5534
  }
5200
5535
  const input = result;
5201
5536
  snapshotCameraProps(input);
@@ -5207,7 +5542,7 @@ function snapshotSource(value) {
5207
5542
  const prototype = Object.getPrototypeOf(value);
5208
5543
  if (prototype !== Object.prototype && prototype !== null) return void 0;
5209
5544
  const keys = Reflect.ownKeys(value);
5210
- if (!keys.includes("map") || !keys.includes("manifestUrl") || keys.some((key) => !["map", "manifestUrl", "developmentOrigin"].includes(String(key))))
5545
+ if (!keys.includes("map") || !keys.includes("manifestUrl") || keys.some((key2) => !["map", "manifestUrl", "developmentOrigin"].includes(String(key2))))
5211
5546
  return void 0;
5212
5547
  const map = Object.getOwnPropertyDescriptor(value, "map");
5213
5548
  const url = Object.getOwnPropertyDescriptor(value, "manifestUrl");
@@ -5232,6 +5567,11 @@ function createMountedMapOwner(ports2) {
5232
5567
  let props;
5233
5568
  let camera = {};
5234
5569
  let mapOptions = Object.freeze({});
5570
+ let transitionMs = 0;
5571
+ let blendSelection;
5572
+ let blendTheme;
5573
+ const blending = () => ports2.surfaces.blending?.() !== false;
5574
+ const selectionTheme = () => blendSelection ? blendTheme : props?.theme;
5235
5575
  let sourceKey;
5236
5576
  let sourceObject;
5237
5577
  let selectedTheme;
@@ -5431,24 +5771,21 @@ function createMountedMapOwner(ports2) {
5431
5771
  const job = { live: true, operations: /* @__PURE__ */ new Set() };
5432
5772
  epoch.job = job;
5433
5773
  let styleReadFailed = false;
5774
+ const blend = blending() ? blendSelection : void 0;
5434
5775
  const owns = () => !disposed && foreground && current === epoch && epoch.live && job.live && epoch.job === job && core.state === source;
5435
5776
  const work = Promise.resolve().then(async () => {
5436
5777
  if (!owns()) return;
5437
5778
  epoch.hosted.validate(source);
5438
5779
  const map = await context(epoch, source);
5439
5780
  if (!owns()) return;
5440
- const previous = epoch.renderer?.currentTarget;
5441
- if (previous && previous.source.theme.name === source.theme.name && previous.source.theme.styleUrl === source.theme.styleUrl && previous.source.theme.revision === source.theme.revision) {
5442
- epoch.renderer.reuseTarget(source);
5443
- return;
5444
- }
5445
- const policy = await map.prepare();
5446
- if (!owns()) return;
5447
- const prepared = await projectNativeResources({
5448
- styleUrl: source.theme.styleUrl,
5449
- developmentOrigin: source.source.developmentOrigin,
5781
+ const renderer = epoch.renderer;
5782
+ const shown = renderer?.activeTarget;
5783
+ const held = [shown, renderer?.currentTarget];
5784
+ const project = async (theme, policy) => (await projectNativeResources({
5785
+ styleUrl: theme.theme.styleUrl,
5786
+ developmentOrigin: theme.source.developmentOrigin,
5450
5787
  policy,
5451
- fontFaces: source.theme.fontFaces?.map((face) => ({
5788
+ fontFaces: theme.theme.fontFaces?.map((face) => ({
5452
5789
  family: face.family,
5453
5790
  source: face.source,
5454
5791
  ...face.style === void 0 ? {} : { style: face.style },
@@ -5473,36 +5810,81 @@ function createMountedMapOwner(ports2) {
5473
5810
  maximumBytes,
5474
5811
  owns
5475
5812
  );
5476
- if (url === source.theme.styleUrl) assertHostedNativeStyleDocument(source, document);
5813
+ if (url === theme.theme.styleUrl)
5814
+ assertHostedNativeStyleDocument(theme, document);
5477
5815
  return document;
5478
5816
  } catch {
5479
- if (url === source.theme.styleUrl && resource?.scope === "style")
5817
+ if (url === theme.theme.styleUrl && resource?.scope === "style")
5480
5818
  styleReadFailed = true;
5481
5819
  throw new NativePreparationError();
5482
5820
  }
5483
5821
  }
5484
- });
5822
+ })).style;
5823
+ let target;
5824
+ if (blend) {
5825
+ const themes = blend.themes.map((name3) => themeSource(source, name3));
5826
+ const key2 = JSON.stringify(themes.map(themeIdentity));
5827
+ if (renderer && shown?.blend?.key === key2) {
5828
+ renderer.reuseTarget(source);
5829
+ if (blendSelection) renderer.setBlendPosition(blendSelection.position);
5830
+ return;
5831
+ }
5832
+ const policy = await map.prepare();
5833
+ if (!owns()) return;
5834
+ const styles = [];
5835
+ for (const theme of themes) {
5836
+ styles.push(heldStyle(held, theme) ?? await project(theme, policy));
5837
+ if (!owns()) return;
5838
+ }
5839
+ const plan = planTileflowThemeBlend(styles, {
5840
+ featureSwitches: "layers",
5841
+ iconImages: "switch"
5842
+ });
5843
+ const position = blendSelection && themeBlendKey(blendSelection) === themeBlendKey(blend) ? blendSelection.position : blend.position;
5844
+ target = {
5845
+ source,
5846
+ style: plan.styleAt(position),
5847
+ blend: {
5848
+ key: key2,
5849
+ plan,
5850
+ position,
5851
+ styles: new Map(themes.map((theme, index) => [themeIdentity(theme), styles[index]]))
5852
+ }
5853
+ };
5854
+ } else {
5855
+ if (renderer && shown && !shown.blend && sameTheme(shown.source, source)) {
5856
+ renderer.reuseTarget(source);
5857
+ return;
5858
+ }
5859
+ const style = heldStyle(held, source);
5860
+ if (renderer && style) {
5861
+ renderer.setTarget({ source, style });
5862
+ notify();
5863
+ return;
5864
+ }
5865
+ const policy = await map.prepare();
5866
+ if (!owns()) return;
5867
+ target = { source, style: await project(source, policy) };
5868
+ }
5485
5869
  if (!owns()) return;
5486
5870
  ports2.surfaces.available?.();
5487
- if (!epoch.renderer)
5488
- epoch.renderer = createNativeRendererOwner(
5489
- map.context,
5490
- { source, style: prepared.style },
5491
- camera,
5492
- {
5493
- surfaces: ports2.surfaces,
5494
- emit(event) {
5495
- if (current === epoch && epoch.live && !disposed) emit(event);
5496
- },
5497
- changed() {
5498
- if (current === epoch && epoch.live) notify();
5499
- },
5500
- interactionsChanged() {
5501
- if (current === epoch && epoch.live && !disposed) notify();
5502
- }
5871
+ if (!epoch.renderer) {
5872
+ epoch.renderer = createNativeRendererOwner(map.context, target, camera, {
5873
+ surfaces: ports2.surfaces,
5874
+ emit(event) {
5875
+ if (current === epoch && epoch.live && !disposed) emit(event);
5876
+ },
5877
+ changed() {
5878
+ if (current === epoch && epoch.live) notify();
5879
+ },
5880
+ interactionsChanged() {
5881
+ if (current === epoch && epoch.live && !disposed) notify();
5503
5882
  }
5504
- );
5505
- else epoch.renderer.setTarget({ source, style: prepared.style });
5883
+ });
5884
+ epoch.renderer.setTransition(transitionMs);
5885
+ } else epoch.renderer.setTarget(target);
5886
+ if (target.blend && blendSelection)
5887
+ epoch.renderer.setBlendPosition(blendSelection.position);
5506
5888
  notify();
5507
5889
  }).catch(() => {
5508
5890
  if (!owns()) return;
@@ -5510,7 +5892,7 @@ function createMountedMapOwner(ports2) {
5510
5892
  cancelJob(epoch);
5511
5893
  epoch.cache.clear();
5512
5894
  if (!disposed && foreground && current === epoch && epoch.live && props) {
5513
- track(core.replace(props.source, { theme: props.theme, colorScheme }));
5895
+ track(core.replace(props.source, { theme: selectionTheme(), colorScheme }));
5514
5896
  }
5515
5897
  return;
5516
5898
  }
@@ -5547,7 +5929,7 @@ function createMountedMapOwner(ports2) {
5547
5929
  function select() {
5548
5930
  if (disposed || !props || !current?.live) return;
5549
5931
  current.hosted.select();
5550
- track(core.replace(props.source, { theme: props.theme, colorScheme }));
5932
+ track(core.replace(props.source, { theme: selectionTheme(), colorScheme }));
5551
5933
  }
5552
5934
  function appearance(theme) {
5553
5935
  if (theme === "system" === Boolean(appearanceRelease)) return;
@@ -5606,16 +5988,27 @@ function createMountedMapOwner(ports2) {
5606
5988
  props = source ? { ...next, source } : next;
5607
5989
  let options;
5608
5990
  let input;
5991
+ let transition;
5992
+ let blend;
5609
5993
  try {
5610
5994
  options = snapshotNativeMapOptions(next.mapOptions);
5611
5995
  input = cameraInput(next);
5996
+ transition = snapshotThemeTransition(next.themeTransition);
5997
+ blend = snapshotThemeBlend(next.themeBlend);
5612
5998
  } catch {
5613
5999
  rendererError();
5614
6000
  return;
5615
6001
  }
5616
- const key = source && JSON.stringify(source);
5617
- const changedSource = !initialized || key !== sourceKey || key === void 0 && sourceObject !== next.source;
5618
- const changedTheme = !initialized || next.theme !== selectedTheme;
6002
+ transitionMs = transition;
6003
+ current?.renderer?.setTransition(transition);
6004
+ const previousBlend = blendSelection;
6005
+ const nearest = blend ? nearestTileflowBlendTheme(blend) : void 0;
6006
+ const changedBlend = Boolean(blend) !== Boolean(previousBlend) || blend && previousBlend && themeBlendKey(blend) !== themeBlendKey(previousBlend) || blend && !blending() && nearest !== blendTheme;
6007
+ blendSelection = blend;
6008
+ if (changedBlend || !blend) blendTheme = nearest;
6009
+ const key2 = source && JSON.stringify(source);
6010
+ const changedSource = !initialized || key2 !== sourceKey || key2 === void 0 && sourceObject !== next.source;
6011
+ const changedTheme = !initialized || !blend && next.theme !== selectedTheme;
5619
6012
  const changedOptions = JSON.stringify(options) !== JSON.stringify(mapOptions);
5620
6013
  camera = input;
5621
6014
  mapOptions = options;
@@ -5624,7 +6017,7 @@ function createMountedMapOwner(ports2) {
5624
6017
  current = void 0;
5625
6018
  if (previous) void retire(previous).catch(() => void 0);
5626
6019
  current = createEpoch(source?.developmentOrigin);
5627
- sourceKey = key;
6020
+ sourceKey = key2;
5628
6021
  sourceObject = next.source;
5629
6022
  }
5630
6023
  selectedTheme = next.theme;
@@ -5634,19 +6027,20 @@ function createMountedMapOwner(ports2) {
5634
6027
  } catch {
5635
6028
  colorScheme = void 0;
5636
6029
  }
5637
- if (changedSource || changedTheme) select();
6030
+ if (changedSource || changedTheme || changedBlend) select();
6031
+ else if (blend && blending()) current?.renderer?.setBlendPosition(blend.position);
5638
6032
  if (changedOptions || changedSource) notify();
5639
6033
  current?.renderer?.afterCommit(camera);
5640
6034
  },
5641
- rootMounted(key, root) {
5642
- if (!disposed && current?.renderer?.snapshot.key === key) current.renderer.bindRoot(root);
6035
+ rootMounted(key2, root) {
6036
+ if (!disposed && current?.renderer?.snapshot.key === key2) current.renderer.bindRoot(root);
5643
6037
  },
5644
- nativeStyleLoaded(key, root) {
5645
- if (disposed || current?.renderer?.snapshot.key !== key) return;
6038
+ nativeStyleLoaded(key2, root) {
6039
+ if (disposed || current?.renderer?.snapshot.key !== key2) return;
5646
6040
  void current.renderer.attach(root).catch(() => void 0);
5647
6041
  },
5648
- layoutChanged(key) {
5649
- if (!disposed && current?.renderer?.snapshot.key === key) current.renderer.layoutChanged();
6042
+ layoutChanged(key2) {
6043
+ if (!disposed && current?.renderer?.snapshot.key === key2) current.renderer.layoutChanged();
5650
6044
  },
5651
6045
  background() {
5652
6046
  nativeLifecycle(false);
@@ -6145,9 +6539,9 @@ function createHostedNativeBindingResolver(readConfiguration) {
6145
6539
  });
6146
6540
  void result.catch(() => void 0);
6147
6541
  const previous = active;
6148
- const own2 = { reject };
6149
- active = own2;
6150
- const current = () => !disposed && generation === sequence && active === own2;
6542
+ const own3 = { reject };
6543
+ active = own3;
6544
+ const current = () => !disposed && generation === sequence && active === own3;
6151
6545
  previous?.reject(new NativeConfigurationError("NATIVE_CONFIGURATION_REPLACED"));
6152
6546
  let metadata;
6153
6547
  try {
@@ -6519,25 +6913,54 @@ var methods = [
6519
6913
  "retireRoot"
6520
6914
  ];
6521
6915
  var positive = (value) => typeof value === "number" && Number.isSafeInteger(value) && value > 0;
6522
- function own(value, name3) {
6916
+ var motionDuration = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && value <= 5e3;
6917
+ var nativeThemeValueLimits = Object.freeze({ values: 8192, images: 64, depth: 32 });
6918
+ var layerOrImage = (value) => typeof value === "string" && value.length > 0 && value.length <= 512;
6919
+ var propertyName = (value) => typeof value === "string" && /^[a-z][a-z-]{0,63}$/u.test(value);
6920
+ function plain(value, depth) {
6921
+ if (value === null || typeof value === "boolean" || typeof value === "string") return true;
6922
+ if (typeof value === "number") return Number.isFinite(value);
6923
+ if (depth >= nativeThemeValueLimits.depth || !value || typeof value !== "object") return false;
6924
+ if (Array.isArray(value)) return value.every((item2) => plain(item2, depth + 1));
6925
+ const prototype = Object.getPrototypeOf(value);
6926
+ if (prototype !== Object.prototype && prototype !== null) return false;
6927
+ return Object.values(value).every((item2) => plain(item2, depth + 1));
6928
+ }
6929
+ function themeValues(values) {
6930
+ if (!values || typeof values !== "object" || Array.isArray(values)) return false;
6931
+ const { paint = [], layout = [], images = [], light: light2 } = values;
6932
+ if (Object.keys(values).some((key2) => !["paint", "layout", "images", "light"].includes(key2)) || !Array.isArray(paint) || !Array.isArray(layout) || !Array.isArray(images) || paint.length + layout.length > nativeThemeValueLimits.values || images.length > nativeThemeValueLimits.images)
6933
+ return false;
6934
+ for (const entry of [...paint, ...layout]) {
6935
+ if (!Array.isArray(entry) || entry.length !== 3 || !layerOrImage(entry[0]) || !propertyName(entry[1]) || !plain(entry[2], 0))
6936
+ return false;
6937
+ }
6938
+ for (const entry of images) {
6939
+ if (!Array.isArray(entry) || entry.length !== 4 || !layerOrImage(entry[0]) || !layerOrImage(entry[1]) || !layerOrImage(entry[2]) || typeof entry[3] !== "number" || !(entry[3] >= 0 && entry[3] <= 1))
6940
+ return false;
6941
+ }
6942
+ if (light2 === void 0) return true;
6943
+ return Boolean(light2) && typeof light2 === "object" && !Array.isArray(light2) && plain(light2, 0);
6944
+ }
6945
+ function own2(value, name3) {
6523
6946
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new NativeSurfaceError();
6524
6947
  const property = Object.getOwnPropertyDescriptor(value, name3);
6525
6948
  if (!property || !("value" in property)) throw new NativeSurfaceError();
6526
6949
  return property.value;
6527
6950
  }
6528
6951
  function eventFromNative(value) {
6529
- const surface = own(value, "surface");
6530
- const style = own(value, "style");
6531
- const sequence = own(value, "sequence");
6532
- const layout = own(value, "layout");
6533
- const kind = own(value, "kind");
6952
+ const surface = own2(value, "surface");
6953
+ const style = own2(value, "style");
6954
+ const sequence = own2(value, "sequence");
6955
+ const layout = own2(value, "layout");
6956
+ const kind = own2(value, "kind");
6534
6957
  if (!isNativeToken(surface) || !isNativeToken(style) || !positive(sequence) || !positive(layout))
6535
6958
  throw new NativeSurfaceError();
6536
6959
  const keys = Reflect.ownKeys(value);
6537
6960
  if (kind === "gesture-start" || kind === "gesture-change" || kind === "gesture-end") {
6538
- const gesture = own(value, "gesture");
6961
+ const gesture = own2(value, "gesture");
6539
6962
  if (!positive(gesture) || keys.length !== 7 || keys.some(
6540
- (key) => typeof key !== "string" || !["surface", "style", "sequence", "layout", "kind", "gesture", "view"].includes(key)
6963
+ (key2) => typeof key2 !== "string" || !["surface", "style", "sequence", "layout", "kind", "gesture", "view"].includes(key2)
6541
6964
  ))
6542
6965
  throw new NativeSurfaceError();
6543
6966
  return Object.freeze({
@@ -6547,11 +6970,11 @@ function eventFromNative(value) {
6547
6970
  layout,
6548
6971
  kind,
6549
6972
  gesture,
6550
- view: snapshotCameraView(own(value, "view"))
6973
+ view: snapshotCameraView(own2(value, "view"))
6551
6974
  });
6552
6975
  }
6553
6976
  if (!["style", "render", "invalidate", "error"].includes(String(kind)) || keys.length !== 5 || keys.some(
6554
- (key) => typeof key !== "string" || !["surface", "style", "sequence", "layout", "kind"].includes(key)
6977
+ (key2) => typeof key2 !== "string" || !["surface", "style", "sequence", "layout", "kind"].includes(key2)
6555
6978
  ))
6556
6979
  throw new NativeSurfaceError();
6557
6980
  return Object.freeze({ surface, style, sequence, layout, kind });
@@ -6579,6 +7002,14 @@ function createNativeSurfaceTransport(locate, listen) {
6579
7002
  available() {
6580
7003
  module();
6581
7004
  },
7005
+ /** Whether the native build can apply blend values; older builds cannot. */
7006
+ blending() {
7007
+ try {
7008
+ return typeof module().applyThemeValues === "function";
7009
+ } catch {
7010
+ return false;
7011
+ }
7012
+ },
6582
7013
  async attach(root, notify, failure3) {
6583
7014
  if (!positive(root) || reservations >= 16) throw new NativeSurfaceError();
6584
7015
  const native = module();
@@ -6629,7 +7060,7 @@ function createNativeSurfaceTransport(locate, listen) {
6629
7060
  unsubscribe = listen((value) => {
6630
7061
  if (!live || !id) return;
6631
7062
  try {
6632
- if (own(value, "surface") !== id) return;
7063
+ if (own2(value, "surface") !== id) return;
6633
7064
  } catch {
6634
7065
  return;
6635
7066
  }
@@ -6710,6 +7141,37 @@ function createNativeSurfaceTransport(locate, listen) {
6710
7141
  if (ack?.cancelled !== true) throw new NativeSurfaceError();
6711
7142
  return Object.freeze({ cancelled: true });
6712
7143
  },
7144
+ ...typeof native.coverSurface === "function" && typeof native.revealSurface === "function" && typeof native.discardSurfaceCover === "function" ? {
7145
+ async cover(duration) {
7146
+ check();
7147
+ if (!motionDuration(duration)) throw new NativeSurfaceError();
7148
+ const ack = await safe(() => native.coverSurface(surface, duration));
7149
+ check();
7150
+ if (typeof ack?.covered !== "boolean") throw new NativeSurfaceError();
7151
+ return ack.covered;
7152
+ },
7153
+ async reveal(duration) {
7154
+ check();
7155
+ if (!motionDuration(duration)) throw new NativeSurfaceError();
7156
+ const ack = await safe(() => native.revealSurface(surface, duration));
7157
+ if (ack?.revealed !== true) throw new NativeSurfaceError();
7158
+ },
7159
+ async discardCover() {
7160
+ const ack = await safe(() => native.discardSurfaceCover(surface));
7161
+ if (ack?.discarded !== true) throw new NativeSurfaceError();
7162
+ }
7163
+ } : {},
7164
+ ...typeof native.applyThemeValues === "function" ? {
7165
+ async applyThemeValues(style, values) {
7166
+ check();
7167
+ if (!isNativeToken(style) || !themeValues(values)) throw new NativeSurfaceError();
7168
+ const ack = await safe(() => native.applyThemeValues(surface, style, values));
7169
+ check();
7170
+ if (!Number.isSafeInteger(ack?.applied) || ack.applied < 0)
7171
+ throw new NativeSurfaceError();
7172
+ return ack.applied;
7173
+ }
7174
+ } : {},
6713
7175
  retire() {
6714
7176
  if (retirement) return retirement;
6715
7177
  live = false;
@@ -6845,6 +7307,10 @@ function NativeScene({
6845
7307
  lifecycle.unbindInteractionHost(host);
6846
7308
  };
6847
7309
  }, [host, lifecycle]);
7310
+ const mapStyle = useMemo2(
7311
+ () => JSON.stringify(scene.style),
7312
+ [scene.style]
7313
+ );
6848
7314
  const [initialViewState] = useState(() => {
6849
7315
  const center = [scene.initialView.center[0], scene.initialView.center[1]];
6850
7316
  Object.freeze(center);
@@ -6894,7 +7360,7 @@ function NativeScene({
6894
7360
  ...mapOptions,
6895
7361
  ref: nativeMap,
6896
7362
  style: fill,
6897
- mapStyle: scene.style,
7363
+ mapStyle,
6898
7364
  onPress: (event) => {
6899
7365
  if (!host.current()) return;
6900
7366
  try {