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