@ibodr/schema 0.2.6 → 0.2.7
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.d.ts +184 -102
- package/dist/index.mjs +575 -364
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { structuredClone, sortByIndex, objectMapFromEntries, getIndices, objectMapEntries, registerDrawLibraryVersion, mapObjectMapValues, uniqueId, safeParseUrl,
|
|
1
|
+
import { structuredClone, sortByIndex, objectMapFromEntries, getIndices, objectMapEntries, registerDrawLibraryVersion, mapObjectMapValues, uniqueId, safeParseUrl, filterEntries, objectMapValues, annotateError, assert } from '@ibodr/utils';
|
|
2
2
|
import { T } from '@ibodr/validate';
|
|
3
3
|
import { createMigrationIds, createRecordMigrationSequence, createMigrationSequence, createRecordType, StoreSchema, RecordType } from '@ibodr/store';
|
|
4
4
|
import { computed } from '@ibodr/state';
|
|
@@ -1046,6 +1046,49 @@ var arrowBindingMigrations = createBindingPropsMigrationSequence({
|
|
|
1046
1046
|
}
|
|
1047
1047
|
]
|
|
1048
1048
|
});
|
|
1049
|
+
var assetVersions = createMigrationIds("com.draw.asset", {
|
|
1050
|
+
AddMeta: 1
|
|
1051
|
+
});
|
|
1052
|
+
var assetMigrations = createRecordMigrationSequence({
|
|
1053
|
+
sequenceId: "com.draw.asset",
|
|
1054
|
+
recordType: "asset",
|
|
1055
|
+
sequence: [
|
|
1056
|
+
{
|
|
1057
|
+
id: assetVersions.AddMeta,
|
|
1058
|
+
up: (record) => {
|
|
1059
|
+
record.meta = {};
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
]
|
|
1063
|
+
});
|
|
1064
|
+
function createAssetRecordType(assets) {
|
|
1065
|
+
return createRecordType("asset", {
|
|
1066
|
+
scope: "document",
|
|
1067
|
+
validator: T.model(
|
|
1068
|
+
"asset",
|
|
1069
|
+
T.union(
|
|
1070
|
+
"type",
|
|
1071
|
+
mapObjectMapValues(
|
|
1072
|
+
assets,
|
|
1073
|
+
(type, { props, meta }) => createAssetValidator(type, props, meta)
|
|
1074
|
+
)
|
|
1075
|
+
)
|
|
1076
|
+
)
|
|
1077
|
+
}).withDefaultProperties(() => ({
|
|
1078
|
+
meta: {}
|
|
1079
|
+
}));
|
|
1080
|
+
}
|
|
1081
|
+
var AssetRecordType = createRecordType("asset", {
|
|
1082
|
+
scope: "document"
|
|
1083
|
+
}).withDefaultProperties(() => ({
|
|
1084
|
+
meta: {}
|
|
1085
|
+
}));
|
|
1086
|
+
function createAssetPropsMigrationSequence(migrations) {
|
|
1087
|
+
return migrations;
|
|
1088
|
+
}
|
|
1089
|
+
function createAssetPropsMigrationIds(assetType, ids) {
|
|
1090
|
+
return mapObjectMapValues(ids, (_k, v) => `com.draw.asset.${assetType}/${v}`);
|
|
1091
|
+
}
|
|
1049
1092
|
var cameraValidator = T.model(
|
|
1050
1093
|
"camera",
|
|
1051
1094
|
T.object({
|
|
@@ -1083,11 +1126,132 @@ var CameraRecordType = createRecordType("camera", {
|
|
|
1083
1126
|
meta: {}
|
|
1084
1127
|
})
|
|
1085
1128
|
);
|
|
1129
|
+
function createCustomRecordType(typeName, config) {
|
|
1130
|
+
return createRecordType(typeName, {
|
|
1131
|
+
scope: config.scope,
|
|
1132
|
+
validator: config.validator
|
|
1133
|
+
}).withDefaultProperties(config.createDefaultProperties ?? (() => ({})));
|
|
1134
|
+
}
|
|
1135
|
+
function processCustomRecordMigrations(records) {
|
|
1136
|
+
const result = [];
|
|
1137
|
+
for (const [typeName, config] of Object.entries(records)) {
|
|
1138
|
+
const sequenceId = `com.draw.${typeName}`;
|
|
1139
|
+
const { migrations } = config;
|
|
1140
|
+
if (!migrations) {
|
|
1141
|
+
result.push(
|
|
1142
|
+
createMigrationSequence({
|
|
1143
|
+
sequenceId,
|
|
1144
|
+
retroactive: true,
|
|
1145
|
+
sequence: []
|
|
1146
|
+
})
|
|
1147
|
+
);
|
|
1148
|
+
} else if ("sequenceId" in migrations) {
|
|
1149
|
+
assert(
|
|
1150
|
+
sequenceId === migrations.sequenceId,
|
|
1151
|
+
`sequenceId mismatch for ${typeName} custom record migrations. Expected '${sequenceId}', got '${migrations.sequenceId}'`
|
|
1152
|
+
);
|
|
1153
|
+
result.push(migrations);
|
|
1154
|
+
} else if ("sequence" in migrations) {
|
|
1155
|
+
result.push(
|
|
1156
|
+
createMigrationSequence({
|
|
1157
|
+
sequenceId,
|
|
1158
|
+
retroactive: true,
|
|
1159
|
+
sequence: migrations.sequence.map((m) => {
|
|
1160
|
+
if (!("id" in m)) return m;
|
|
1161
|
+
return {
|
|
1162
|
+
id: m.id,
|
|
1163
|
+
dependsOn: m.dependsOn,
|
|
1164
|
+
scope: "record",
|
|
1165
|
+
filter: (r) => r.typeName === typeName,
|
|
1166
|
+
up: (record) => {
|
|
1167
|
+
const result2 = m.up(record);
|
|
1168
|
+
if (result2) return result2;
|
|
1169
|
+
},
|
|
1170
|
+
down: typeof m.down === "function" ? (record) => {
|
|
1171
|
+
const result2 = m.down(record);
|
|
1172
|
+
if (result2) return result2;
|
|
1173
|
+
} : void 0
|
|
1174
|
+
};
|
|
1175
|
+
})
|
|
1176
|
+
})
|
|
1177
|
+
);
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
return result;
|
|
1181
|
+
}
|
|
1182
|
+
function createCustomRecordMigrationIds(recordType, ids) {
|
|
1183
|
+
return mapObjectMapValues(ids, (_k, v) => `com.draw.${recordType}/${v}`);
|
|
1184
|
+
}
|
|
1185
|
+
function createCustomRecordMigrationSequence(migrations) {
|
|
1186
|
+
return migrations;
|
|
1187
|
+
}
|
|
1188
|
+
function createCustomRecordId(typeName, id) {
|
|
1189
|
+
return `${typeName}:${id ?? uniqueId()}`;
|
|
1190
|
+
}
|
|
1191
|
+
function isCustomRecordId(typeName, id) {
|
|
1192
|
+
if (!id) return false;
|
|
1193
|
+
return id.startsWith(`${typeName}:`);
|
|
1194
|
+
}
|
|
1195
|
+
function isCustomRecord(typeName, record) {
|
|
1196
|
+
if (!record) return false;
|
|
1197
|
+
return record.typeName === typeName;
|
|
1198
|
+
}
|
|
1199
|
+
var documentValidator = T.model(
|
|
1200
|
+
"document",
|
|
1201
|
+
T.object({
|
|
1202
|
+
typeName: T.literal("document"),
|
|
1203
|
+
id: T.literal("document:document"),
|
|
1204
|
+
gridSize: T.number,
|
|
1205
|
+
name: T.string,
|
|
1206
|
+
meta: T.jsonValue
|
|
1207
|
+
})
|
|
1208
|
+
);
|
|
1209
|
+
function isDocument(record) {
|
|
1210
|
+
if (!record) return false;
|
|
1211
|
+
return record.typeName === "document";
|
|
1212
|
+
}
|
|
1213
|
+
var documentVersions = createMigrationIds("com.draw.document", {
|
|
1214
|
+
AddName: 1,
|
|
1215
|
+
AddMeta: 2
|
|
1216
|
+
});
|
|
1217
|
+
var documentMigrations = createRecordMigrationSequence({
|
|
1218
|
+
sequenceId: "com.draw.document",
|
|
1219
|
+
recordType: "document",
|
|
1220
|
+
sequence: [
|
|
1221
|
+
{
|
|
1222
|
+
id: documentVersions.AddName,
|
|
1223
|
+
up: (document) => {
|
|
1224
|
+
document.name = "";
|
|
1225
|
+
},
|
|
1226
|
+
down: (document) => {
|
|
1227
|
+
delete document.name;
|
|
1228
|
+
}
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
id: documentVersions.AddMeta,
|
|
1232
|
+
up: (record) => {
|
|
1233
|
+
record.meta = {};
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
]
|
|
1237
|
+
});
|
|
1238
|
+
var DocumentRecordType = createRecordType("document", {
|
|
1239
|
+
validator: documentValidator,
|
|
1240
|
+
scope: "document"
|
|
1241
|
+
}).withDefaultProperties(
|
|
1242
|
+
() => ({
|
|
1243
|
+
gridSize: 10,
|
|
1244
|
+
name: "",
|
|
1245
|
+
meta: {}
|
|
1246
|
+
})
|
|
1247
|
+
);
|
|
1248
|
+
var DrDOCUMENT_ID = DocumentRecordType.createId("document");
|
|
1086
1249
|
var TL_CURSOR_TYPES = /* @__PURE__ */ new Set([
|
|
1087
1250
|
"none",
|
|
1088
1251
|
"default",
|
|
1089
1252
|
"pointer",
|
|
1090
1253
|
"cross",
|
|
1254
|
+
"comment",
|
|
1091
1255
|
"grab",
|
|
1092
1256
|
"rotate",
|
|
1093
1257
|
"grabbing",
|
|
@@ -1173,9 +1337,80 @@ var PageRecordType = createRecordType("page", {
|
|
|
1173
1337
|
}).withDefaultProperties(() => ({
|
|
1174
1338
|
meta: {}
|
|
1175
1339
|
}));
|
|
1340
|
+
function isPage(record) {
|
|
1341
|
+
if (!record) return false;
|
|
1342
|
+
return record.typeName === "page";
|
|
1343
|
+
}
|
|
1176
1344
|
function isPageId(id) {
|
|
1177
1345
|
return PageRecordType.isId(id);
|
|
1178
1346
|
}
|
|
1347
|
+
var userIdValidator = idValidator("user");
|
|
1348
|
+
var userVersions = createMigrationIds("com.draw.user", {
|
|
1349
|
+
Initial: 1
|
|
1350
|
+
});
|
|
1351
|
+
var userMigrations = createRecordMigrationSequence({
|
|
1352
|
+
sequenceId: "com.draw.user",
|
|
1353
|
+
recordType: "user",
|
|
1354
|
+
sequence: [
|
|
1355
|
+
{
|
|
1356
|
+
id: userVersions.Initial,
|
|
1357
|
+
up: (_record) => {
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
]
|
|
1361
|
+
});
|
|
1362
|
+
function createUserRecordType(config) {
|
|
1363
|
+
const metaConfig = config?.meta;
|
|
1364
|
+
const metaValidator = metaConfig ? T.object(
|
|
1365
|
+
Object.fromEntries(
|
|
1366
|
+
Object.entries(metaConfig).map(([key, v]) => [
|
|
1367
|
+
key,
|
|
1368
|
+
new T.Validator((value) => {
|
|
1369
|
+
if (value === void 0) return void 0;
|
|
1370
|
+
return v.validate(value);
|
|
1371
|
+
})
|
|
1372
|
+
])
|
|
1373
|
+
)
|
|
1374
|
+
).allowUnknownProperties() : T.jsonValue;
|
|
1375
|
+
const validator = T.model(
|
|
1376
|
+
"user",
|
|
1377
|
+
T.object({
|
|
1378
|
+
typeName: T.literal("user"),
|
|
1379
|
+
id: userIdValidator,
|
|
1380
|
+
name: T.string,
|
|
1381
|
+
color: T.string,
|
|
1382
|
+
imageUrl: T.string,
|
|
1383
|
+
meta: metaValidator
|
|
1384
|
+
})
|
|
1385
|
+
);
|
|
1386
|
+
return createRecordType("user", {
|
|
1387
|
+
validator,
|
|
1388
|
+
scope: "document"
|
|
1389
|
+
}).withDefaultProperties(() => ({
|
|
1390
|
+
name: "",
|
|
1391
|
+
color: "",
|
|
1392
|
+
imageUrl: "",
|
|
1393
|
+
meta: {}
|
|
1394
|
+
}));
|
|
1395
|
+
}
|
|
1396
|
+
T.model(
|
|
1397
|
+
"user",
|
|
1398
|
+
T.object({
|
|
1399
|
+
typeName: T.literal("user"),
|
|
1400
|
+
id: userIdValidator,
|
|
1401
|
+
name: T.string,
|
|
1402
|
+
color: T.string,
|
|
1403
|
+
imageUrl: T.string,
|
|
1404
|
+
meta: T.jsonValue
|
|
1405
|
+
})
|
|
1406
|
+
);
|
|
1407
|
+
var UserRecordType = createUserRecordType();
|
|
1408
|
+
function isUserId(id) {
|
|
1409
|
+
return UserRecordType.isId(id);
|
|
1410
|
+
}
|
|
1411
|
+
function createUserId(id) {
|
|
1412
|
+
return UserRecordType.createId(id);
|
|
1413
|
+
}
|
|
1179
1414
|
|
|
1180
1415
|
// src/records/DrInstance.ts
|
|
1181
1416
|
var DR_BOARD_BACKGROUND_TYPES = [
|
|
@@ -1272,7 +1507,7 @@ function createInstanceRecordType(stylesById) {
|
|
|
1272
1507
|
typeName: T.literal("instance"),
|
|
1273
1508
|
id: idValidator("instance"),
|
|
1274
1509
|
currentPageId: pageIdValidator,
|
|
1275
|
-
followingUserId:
|
|
1510
|
+
followingUserId: userIdValidator.nullable(),
|
|
1276
1511
|
brush: boxModelValidator.nullable(),
|
|
1277
1512
|
opacityForNextShape: opacityValidator,
|
|
1278
1513
|
stylesForNextShape: T.object(stylesForNextShapeValidators),
|
|
@@ -1290,7 +1525,7 @@ function createInstanceRecordType(stylesById) {
|
|
|
1290
1525
|
backgroundType: T.literalEnum(...DR_BOARD_BACKGROUND_TYPES),
|
|
1291
1526
|
chatMessage: T.string,
|
|
1292
1527
|
isChatting: T.boolean,
|
|
1293
|
-
highlightedUserIds: T.arrayOf(
|
|
1528
|
+
highlightedUserIds: T.arrayOf(userIdValidator),
|
|
1294
1529
|
isFocused: T.boolean,
|
|
1295
1530
|
devicePixelRatio: T.number,
|
|
1296
1531
|
isCoarsePointer: T.boolean,
|
|
@@ -1356,7 +1591,7 @@ function createInstanceRecordType(stylesById) {
|
|
|
1356
1591
|
rotation: 0
|
|
1357
1592
|
},
|
|
1358
1593
|
isFocusMode: false,
|
|
1359
|
-
exportBackground:
|
|
1594
|
+
exportBackground: true,
|
|
1360
1595
|
isDebugMode: false,
|
|
1361
1596
|
isToolLocked: false,
|
|
1362
1597
|
screenBounds: { x: 0, y: 0, w: 1080, h: 720 },
|
|
@@ -1788,7 +2023,11 @@ var InstancePageStateRecordType = createRecordType(
|
|
|
1788
2023
|
ephemeralKeys: {
|
|
1789
2024
|
pageId: false,
|
|
1790
2025
|
selectedShapeIds: false,
|
|
1791
|
-
editingShapeId:
|
|
2026
|
+
// editingShapeId is set with `history: 'ignore'`, so entering the editing
|
|
2027
|
+
// state is never undoable. Marking it ephemeral keeps undo/redo from
|
|
2028
|
+
// reapplying a stale editingShapeId (e.g. after a shape it pointed at was
|
|
2029
|
+
// deleted), which could leave the editor pointing at a missing shape.
|
|
2030
|
+
editingShapeId: true,
|
|
1792
2031
|
croppingShapeId: false,
|
|
1793
2032
|
meta: false,
|
|
1794
2033
|
hintingShapeIds: true,
|
|
@@ -1852,10 +2091,10 @@ var instancePresenceValidator = T.model(
|
|
|
1852
2091
|
T.object({
|
|
1853
2092
|
typeName: T.literal("instance_presence"),
|
|
1854
2093
|
id: idValidator("instance_presence"),
|
|
1855
|
-
userId:
|
|
2094
|
+
userId: userIdValidator,
|
|
1856
2095
|
userName: T.string,
|
|
1857
2096
|
lastActivityTimestamp: T.number.nullable(),
|
|
1858
|
-
followingUserId:
|
|
2097
|
+
followingUserId: userIdValidator.nullable(),
|
|
1859
2098
|
cursor: T.object({
|
|
1860
2099
|
x: T.number,
|
|
1861
2100
|
y: T.number,
|
|
@@ -1898,350 +2137,68 @@ var instancePresenceMigrations = createRecordMigrationSequence({
|
|
|
1898
2137
|
}
|
|
1899
2138
|
},
|
|
1900
2139
|
{
|
|
1901
|
-
id: instancePresenceVersions.RemoveInstanceId,
|
|
1902
|
-
up: (instance) => {
|
|
1903
|
-
delete instance.instanceId;
|
|
1904
|
-
}
|
|
1905
|
-
},
|
|
1906
|
-
{
|
|
1907
|
-
id: instancePresenceVersions.AddChatMessage,
|
|
1908
|
-
up: (instance) => {
|
|
1909
|
-
instance.chatMessage = "";
|
|
1910
|
-
}
|
|
1911
|
-
},
|
|
1912
|
-
{
|
|
1913
|
-
id: instancePresenceVersions.AddMeta,
|
|
1914
|
-
up: (record) => {
|
|
1915
|
-
record.meta = {};
|
|
1916
|
-
}
|
|
1917
|
-
},
|
|
1918
|
-
{
|
|
1919
|
-
id: instancePresenceVersions.RenameSelectedShapeIds,
|
|
1920
|
-
up: (_record) => {
|
|
1921
|
-
}
|
|
1922
|
-
},
|
|
1923
|
-
{
|
|
1924
|
-
id: instancePresenceVersions.NullableCameraCursor,
|
|
1925
|
-
up: (_record) => {
|
|
1926
|
-
},
|
|
1927
|
-
down: (record) => {
|
|
1928
|
-
if (record.camera === null) {
|
|
1929
|
-
record.camera = { x: 0, y: 0, z: 1 };
|
|
1930
|
-
}
|
|
1931
|
-
if (record.lastActivityTimestamp === null) {
|
|
1932
|
-
record.lastActivityTimestamp = 0;
|
|
1933
|
-
}
|
|
1934
|
-
if (record.cursor === null) {
|
|
1935
|
-
record.cursor = { type: "default", x: 0, y: 0, rotation: 0 };
|
|
1936
|
-
}
|
|
1937
|
-
if (record.screenBounds === null) {
|
|
1938
|
-
record.screenBounds = { x: 0, y: 0, w: 1, h: 1 };
|
|
1939
|
-
}
|
|
1940
|
-
}
|
|
1941
|
-
}
|
|
1942
|
-
]
|
|
1943
|
-
});
|
|
1944
|
-
var InstancePresenceRecordType = createRecordType(
|
|
1945
|
-
"instance_presence",
|
|
1946
|
-
{
|
|
1947
|
-
validator: instancePresenceValidator,
|
|
1948
|
-
scope: "presence"
|
|
1949
|
-
}
|
|
1950
|
-
).withDefaultProperties(() => ({
|
|
1951
|
-
lastActivityTimestamp: null,
|
|
1952
|
-
followingUserId: null,
|
|
1953
|
-
color: "#FF0000",
|
|
1954
|
-
camera: null,
|
|
1955
|
-
cursor: null,
|
|
1956
|
-
screenBounds: null,
|
|
1957
|
-
selectedShapeIds: [],
|
|
1958
|
-
brush: null,
|
|
1959
|
-
scribbles: [],
|
|
1960
|
-
chatMessage: "",
|
|
1961
|
-
meta: {}
|
|
1962
|
-
}));
|
|
1963
|
-
|
|
1964
|
-
// src/createPresenceStateDerivation.ts
|
|
1965
|
-
function createPresenceStateDerivation($user, opts) {
|
|
1966
|
-
const { instanceId, getUserPresence: _getUserPresence } = opts ?? {};
|
|
1967
|
-
const getUserPresence = _getUserPresence ?? getDefaultUserPresence;
|
|
1968
|
-
return (store) => {
|
|
1969
|
-
return computed("instancePresence", () => {
|
|
1970
|
-
const user = $user.get();
|
|
1971
|
-
if (!user) return null;
|
|
1972
|
-
const state = getUserPresence(store, user);
|
|
1973
|
-
if (!state) return null;
|
|
1974
|
-
return InstancePresenceRecordType.create({
|
|
1975
|
-
...state,
|
|
1976
|
-
id: instanceId ?? InstancePresenceRecordType.createId(store.id)
|
|
1977
|
-
});
|
|
1978
|
-
});
|
|
1979
|
-
};
|
|
1980
|
-
}
|
|
1981
|
-
function getDefaultUserPresence(store, user) {
|
|
1982
|
-
const instance = store.get(DrINSTANCE_ID);
|
|
1983
|
-
const pageState = store.get(InstancePageStateRecordType.createId(instance?.currentPageId));
|
|
1984
|
-
const camera = store.get(CameraRecordType.createId(instance?.currentPageId));
|
|
1985
|
-
const pointer = store.get(DrPOINTER_ID);
|
|
1986
|
-
if (!pageState || !instance || !camera || !pointer) {
|
|
1987
|
-
return null;
|
|
1988
|
-
}
|
|
1989
|
-
return {
|
|
1990
|
-
selectedShapeIds: pageState.selectedShapeIds,
|
|
1991
|
-
brush: instance.brush,
|
|
1992
|
-
scribbles: instance.scribbles,
|
|
1993
|
-
userId: user.id,
|
|
1994
|
-
userName: user.name,
|
|
1995
|
-
followingUserId: instance.followingUserId,
|
|
1996
|
-
camera: {
|
|
1997
|
-
x: camera.x,
|
|
1998
|
-
y: camera.y,
|
|
1999
|
-
z: camera.z
|
|
2000
|
-
},
|
|
2001
|
-
color: user.color || "#FF0000",
|
|
2002
|
-
currentPageId: instance.currentPageId,
|
|
2003
|
-
cursor: {
|
|
2004
|
-
x: pointer.x,
|
|
2005
|
-
y: pointer.y,
|
|
2006
|
-
rotation: instance.cursor.rotation,
|
|
2007
|
-
type: instance.cursor.type
|
|
2008
|
-
},
|
|
2009
|
-
lastActivityTimestamp: pointer.lastActivityTimestamp,
|
|
2010
|
-
screenBounds: instance.screenBounds,
|
|
2011
|
-
chatMessage: instance.chatMessage,
|
|
2012
|
-
meta: {}
|
|
2013
|
-
};
|
|
2014
|
-
}
|
|
2015
|
-
var assetVersions = createMigrationIds("com.draw.asset", {
|
|
2016
|
-
AddMeta: 1
|
|
2017
|
-
});
|
|
2018
|
-
var assetMigrations = createRecordMigrationSequence({
|
|
2019
|
-
sequenceId: "com.draw.asset",
|
|
2020
|
-
recordType: "asset",
|
|
2021
|
-
sequence: [
|
|
2022
|
-
{
|
|
2023
|
-
id: assetVersions.AddMeta,
|
|
2024
|
-
up: (record) => {
|
|
2025
|
-
record.meta = {};
|
|
2026
|
-
}
|
|
2027
|
-
}
|
|
2028
|
-
]
|
|
2029
|
-
});
|
|
2030
|
-
function createAssetRecordType(assets) {
|
|
2031
|
-
return createRecordType("asset", {
|
|
2032
|
-
scope: "document",
|
|
2033
|
-
validator: T.model(
|
|
2034
|
-
"asset",
|
|
2035
|
-
T.union(
|
|
2036
|
-
"type",
|
|
2037
|
-
mapObjectMapValues(
|
|
2038
|
-
assets,
|
|
2039
|
-
(type, { props, meta }) => createAssetValidator(type, props, meta)
|
|
2040
|
-
)
|
|
2041
|
-
)
|
|
2042
|
-
)
|
|
2043
|
-
}).withDefaultProperties(() => ({
|
|
2044
|
-
meta: {}
|
|
2045
|
-
}));
|
|
2046
|
-
}
|
|
2047
|
-
var AssetRecordType = createRecordType("asset", {
|
|
2048
|
-
scope: "document"
|
|
2049
|
-
}).withDefaultProperties(() => ({
|
|
2050
|
-
meta: {}
|
|
2051
|
-
}));
|
|
2052
|
-
function createAssetPropsMigrationSequence(migrations) {
|
|
2053
|
-
return migrations;
|
|
2054
|
-
}
|
|
2055
|
-
function createAssetPropsMigrationIds(assetType, ids) {
|
|
2056
|
-
return mapObjectMapValues(ids, (_k, v) => `com.draw.asset.${assetType}/${v}`);
|
|
2057
|
-
}
|
|
2058
|
-
function createCustomRecordType(typeName, config) {
|
|
2059
|
-
return createRecordType(typeName, {
|
|
2060
|
-
scope: config.scope,
|
|
2061
|
-
validator: config.validator
|
|
2062
|
-
}).withDefaultProperties(config.createDefaultProperties ?? (() => ({})));
|
|
2063
|
-
}
|
|
2064
|
-
function processCustomRecordMigrations(records) {
|
|
2065
|
-
const result = [];
|
|
2066
|
-
for (const [typeName, config] of Object.entries(records)) {
|
|
2067
|
-
const sequenceId = `com.draw.${typeName}`;
|
|
2068
|
-
const { migrations } = config;
|
|
2069
|
-
if (!migrations) {
|
|
2070
|
-
result.push(
|
|
2071
|
-
createMigrationSequence({
|
|
2072
|
-
sequenceId,
|
|
2073
|
-
retroactive: true,
|
|
2074
|
-
sequence: []
|
|
2075
|
-
})
|
|
2076
|
-
);
|
|
2077
|
-
} else if ("sequenceId" in migrations) {
|
|
2078
|
-
assert(
|
|
2079
|
-
sequenceId === migrations.sequenceId,
|
|
2080
|
-
`sequenceId mismatch for ${typeName} custom record migrations. Expected '${sequenceId}', got '${migrations.sequenceId}'`
|
|
2081
|
-
);
|
|
2082
|
-
result.push(migrations);
|
|
2083
|
-
} else if ("sequence" in migrations) {
|
|
2084
|
-
result.push(
|
|
2085
|
-
createMigrationSequence({
|
|
2086
|
-
sequenceId,
|
|
2087
|
-
retroactive: true,
|
|
2088
|
-
sequence: migrations.sequence.map((m) => {
|
|
2089
|
-
if (!("id" in m)) return m;
|
|
2090
|
-
return {
|
|
2091
|
-
id: m.id,
|
|
2092
|
-
dependsOn: m.dependsOn,
|
|
2093
|
-
scope: "record",
|
|
2094
|
-
filter: (r) => r.typeName === typeName,
|
|
2095
|
-
up: (record) => {
|
|
2096
|
-
const result2 = m.up(record);
|
|
2097
|
-
if (result2) return result2;
|
|
2098
|
-
},
|
|
2099
|
-
down: typeof m.down === "function" ? (record) => {
|
|
2100
|
-
const result2 = m.down(record);
|
|
2101
|
-
if (result2) return result2;
|
|
2102
|
-
} : void 0
|
|
2103
|
-
};
|
|
2104
|
-
})
|
|
2105
|
-
})
|
|
2106
|
-
);
|
|
2107
|
-
}
|
|
2108
|
-
}
|
|
2109
|
-
return result;
|
|
2110
|
-
}
|
|
2111
|
-
function createCustomRecordMigrationIds(recordType, ids) {
|
|
2112
|
-
return mapObjectMapValues(ids, (_k, v) => `com.draw.${recordType}/${v}`);
|
|
2113
|
-
}
|
|
2114
|
-
function createCustomRecordMigrationSequence(migrations) {
|
|
2115
|
-
return migrations;
|
|
2116
|
-
}
|
|
2117
|
-
function createCustomRecordId(typeName, id) {
|
|
2118
|
-
return `${typeName}:${id ?? uniqueId()}`;
|
|
2119
|
-
}
|
|
2120
|
-
function isCustomRecordId(typeName, id) {
|
|
2121
|
-
if (!id) return false;
|
|
2122
|
-
return id.startsWith(`${typeName}:`);
|
|
2123
|
-
}
|
|
2124
|
-
function isCustomRecord(typeName, record) {
|
|
2125
|
-
if (!record) return false;
|
|
2126
|
-
return record.typeName === typeName;
|
|
2127
|
-
}
|
|
2128
|
-
var documentValidator = T.model(
|
|
2129
|
-
"document",
|
|
2130
|
-
T.object({
|
|
2131
|
-
typeName: T.literal("document"),
|
|
2132
|
-
id: T.literal("document:document"),
|
|
2133
|
-
gridSize: T.number,
|
|
2134
|
-
name: T.string,
|
|
2135
|
-
meta: T.jsonValue
|
|
2136
|
-
})
|
|
2137
|
-
);
|
|
2138
|
-
function isDocument(record) {
|
|
2139
|
-
if (!record) return false;
|
|
2140
|
-
return record.typeName === "document";
|
|
2141
|
-
}
|
|
2142
|
-
var documentVersions = createMigrationIds("com.draw.document", {
|
|
2143
|
-
AddName: 1,
|
|
2144
|
-
AddMeta: 2
|
|
2145
|
-
});
|
|
2146
|
-
var documentMigrations = createRecordMigrationSequence({
|
|
2147
|
-
sequenceId: "com.draw.document",
|
|
2148
|
-
recordType: "document",
|
|
2149
|
-
sequence: [
|
|
2150
|
-
{
|
|
2151
|
-
id: documentVersions.AddName,
|
|
2152
|
-
up: (document) => {
|
|
2153
|
-
document.name = "";
|
|
2154
|
-
},
|
|
2155
|
-
down: (document) => {
|
|
2156
|
-
delete document.name;
|
|
2157
|
-
}
|
|
2158
|
-
},
|
|
2159
|
-
{
|
|
2160
|
-
id: documentVersions.AddMeta,
|
|
2161
|
-
up: (record) => {
|
|
2162
|
-
record.meta = {};
|
|
2163
|
-
}
|
|
2164
|
-
}
|
|
2165
|
-
]
|
|
2166
|
-
});
|
|
2167
|
-
var DocumentRecordType = createRecordType("document", {
|
|
2168
|
-
validator: documentValidator,
|
|
2169
|
-
scope: "document"
|
|
2170
|
-
}).withDefaultProperties(
|
|
2171
|
-
() => ({
|
|
2172
|
-
gridSize: 10,
|
|
2173
|
-
name: "",
|
|
2174
|
-
meta: {}
|
|
2175
|
-
})
|
|
2176
|
-
);
|
|
2177
|
-
var DrDOCUMENT_ID = DocumentRecordType.createId("document");
|
|
2178
|
-
var userIdValidator = idValidator("user");
|
|
2179
|
-
var userVersions = createMigrationIds("com.draw.user", {
|
|
2180
|
-
Initial: 1
|
|
2181
|
-
});
|
|
2182
|
-
var userMigrations = createRecordMigrationSequence({
|
|
2183
|
-
sequenceId: "com.draw.user",
|
|
2184
|
-
recordType: "user",
|
|
2185
|
-
sequence: [
|
|
2140
|
+
id: instancePresenceVersions.RemoveInstanceId,
|
|
2141
|
+
up: (instance) => {
|
|
2142
|
+
delete instance.instanceId;
|
|
2143
|
+
}
|
|
2144
|
+
},
|
|
2186
2145
|
{
|
|
2187
|
-
id:
|
|
2146
|
+
id: instancePresenceVersions.AddChatMessage,
|
|
2147
|
+
up: (instance) => {
|
|
2148
|
+
instance.chatMessage = "";
|
|
2149
|
+
}
|
|
2150
|
+
},
|
|
2151
|
+
{
|
|
2152
|
+
id: instancePresenceVersions.AddMeta,
|
|
2153
|
+
up: (record) => {
|
|
2154
|
+
record.meta = {};
|
|
2155
|
+
}
|
|
2156
|
+
},
|
|
2157
|
+
{
|
|
2158
|
+
id: instancePresenceVersions.RenameSelectedShapeIds,
|
|
2159
|
+
up: (_record) => {
|
|
2160
|
+
}
|
|
2161
|
+
},
|
|
2162
|
+
{
|
|
2163
|
+
id: instancePresenceVersions.NullableCameraCursor,
|
|
2188
2164
|
up: (_record) => {
|
|
2165
|
+
},
|
|
2166
|
+
down: (record) => {
|
|
2167
|
+
if (record.camera === null) {
|
|
2168
|
+
record.camera = { x: 0, y: 0, z: 1 };
|
|
2169
|
+
}
|
|
2170
|
+
if (record.lastActivityTimestamp === null) {
|
|
2171
|
+
record.lastActivityTimestamp = 0;
|
|
2172
|
+
}
|
|
2173
|
+
if (record.cursor === null) {
|
|
2174
|
+
record.cursor = { type: "default", x: 0, y: 0, rotation: 0 };
|
|
2175
|
+
}
|
|
2176
|
+
if (record.screenBounds === null) {
|
|
2177
|
+
record.screenBounds = { x: 0, y: 0, w: 1, h: 1 };
|
|
2178
|
+
}
|
|
2189
2179
|
}
|
|
2190
2180
|
}
|
|
2191
2181
|
]
|
|
2192
2182
|
});
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
color: T.string,
|
|
2213
|
-
imageUrl: T.string,
|
|
2214
|
-
meta: metaValidator
|
|
2215
|
-
})
|
|
2216
|
-
);
|
|
2217
|
-
return createRecordType("user", {
|
|
2218
|
-
validator,
|
|
2219
|
-
scope: "document"
|
|
2220
|
-
}).withDefaultProperties(() => ({
|
|
2221
|
-
name: "",
|
|
2222
|
-
color: "",
|
|
2223
|
-
imageUrl: "",
|
|
2224
|
-
meta: {}
|
|
2225
|
-
}));
|
|
2226
|
-
}
|
|
2227
|
-
T.model(
|
|
2228
|
-
"user",
|
|
2229
|
-
T.object({
|
|
2230
|
-
typeName: T.literal("user"),
|
|
2231
|
-
id: userIdValidator,
|
|
2232
|
-
name: T.string,
|
|
2233
|
-
color: T.string,
|
|
2234
|
-
imageUrl: T.string,
|
|
2235
|
-
meta: T.jsonValue
|
|
2236
|
-
})
|
|
2237
|
-
);
|
|
2238
|
-
var UserRecordType = createUserRecordType();
|
|
2239
|
-
function isUserId(id) {
|
|
2240
|
-
return UserRecordType.isId(id);
|
|
2241
|
-
}
|
|
2242
|
-
function createUserId(id) {
|
|
2243
|
-
return UserRecordType.createId(id);
|
|
2244
|
-
}
|
|
2183
|
+
var InstancePresenceRecordType = createRecordType(
|
|
2184
|
+
"instance_presence",
|
|
2185
|
+
{
|
|
2186
|
+
validator: instancePresenceValidator,
|
|
2187
|
+
scope: "presence"
|
|
2188
|
+
}
|
|
2189
|
+
).withDefaultProperties(() => ({
|
|
2190
|
+
lastActivityTimestamp: null,
|
|
2191
|
+
followingUserId: null,
|
|
2192
|
+
color: "#FF0000",
|
|
2193
|
+
camera: null,
|
|
2194
|
+
cursor: null,
|
|
2195
|
+
screenBounds: null,
|
|
2196
|
+
selectedShapeIds: [],
|
|
2197
|
+
brush: null,
|
|
2198
|
+
scribbles: [],
|
|
2199
|
+
chatMessage: "",
|
|
2200
|
+
meta: {}
|
|
2201
|
+
}));
|
|
2245
2202
|
var bookmarkShapeProps = {
|
|
2246
2203
|
w: T.nonZeroNumber,
|
|
2247
2204
|
h: T.nonZeroNumber,
|
|
@@ -2275,12 +2232,20 @@ var bookmarkShapeMigrations = createShapePropsMigrationSequence({
|
|
|
2275
2232
|
}
|
|
2276
2233
|
]
|
|
2277
2234
|
});
|
|
2235
|
+
|
|
2236
|
+
// src/misc/b64Vecs.ts
|
|
2278
2237
|
var FIRST_POINT_B64_LENGTH = 16;
|
|
2238
|
+
var FIRST_POINT_2D_B64_LENGTH = 12;
|
|
2239
|
+
var DEFAULT_PRESSURE = 0.5;
|
|
2240
|
+
var DIM_2D = 2;
|
|
2241
|
+
var DIM_3D = 3;
|
|
2279
2242
|
var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
2280
2243
|
var B64_LOOKUP = new Uint8Array(128);
|
|
2281
2244
|
for (let i = 0; i < 64; i++) {
|
|
2282
2245
|
B64_LOOKUP[BASE64_CHARS.charCodeAt(i)] = i;
|
|
2283
2246
|
}
|
|
2247
|
+
var SIX_BIT_MASK = 63;
|
|
2248
|
+
var PADDING_CHAR_CODE = "=".charCodeAt(0);
|
|
2284
2249
|
var POW2 = new Float64Array(31);
|
|
2285
2250
|
for (let i = 0; i < 31; i++) {
|
|
2286
2251
|
POW2[i] = Math.pow(2, i - 15);
|
|
@@ -2308,10 +2273,19 @@ function nativeBase64ToUint8Array(base64) {
|
|
|
2308
2273
|
return Uint8Array.fromBase64(base64);
|
|
2309
2274
|
}
|
|
2310
2275
|
function fallbackBase64ToUint8Array(base64) {
|
|
2311
|
-
const
|
|
2276
|
+
const paddedLength = base64.length;
|
|
2277
|
+
let padding = 0;
|
|
2278
|
+
if (paddedLength > 0 && base64.charCodeAt(paddedLength - 1) === PADDING_CHAR_CODE) {
|
|
2279
|
+
padding++;
|
|
2280
|
+
if (paddedLength > 1 && base64.charCodeAt(paddedLength - 2) === PADDING_CHAR_CODE) {
|
|
2281
|
+
padding++;
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
const numBytes = Math.floor(paddedLength * 3 / 4) - padding;
|
|
2312
2285
|
const bytes = new Uint8Array(numBytes);
|
|
2313
2286
|
let byteIndex = 0;
|
|
2314
|
-
|
|
2287
|
+
const fullGroups = Math.floor((paddedLength - padding) / 4) * 4;
|
|
2288
|
+
for (let i = 0; i < fullGroups; i += 4) {
|
|
2315
2289
|
const c0 = B64_LOOKUP[base64.charCodeAt(i)];
|
|
2316
2290
|
const c1 = B64_LOOKUP[base64.charCodeAt(i + 1)];
|
|
2317
2291
|
const c2 = B64_LOOKUP[base64.charCodeAt(i + 2)];
|
|
@@ -2321,20 +2295,45 @@ function fallbackBase64ToUint8Array(base64) {
|
|
|
2321
2295
|
bytes[byteIndex++] = bitmap >> 8 & 255;
|
|
2322
2296
|
bytes[byteIndex++] = bitmap & 255;
|
|
2323
2297
|
}
|
|
2298
|
+
if (padding === 1) {
|
|
2299
|
+
const c0 = B64_LOOKUP[base64.charCodeAt(fullGroups)];
|
|
2300
|
+
const c1 = B64_LOOKUP[base64.charCodeAt(fullGroups + 1)];
|
|
2301
|
+
const c2 = B64_LOOKUP[base64.charCodeAt(fullGroups + 2)];
|
|
2302
|
+
const bitmap = c0 << 18 | c1 << 12 | c2 << 6;
|
|
2303
|
+
bytes[byteIndex++] = bitmap >> 16 & 255;
|
|
2304
|
+
bytes[byteIndex++] = bitmap >> 8 & 255;
|
|
2305
|
+
} else if (padding === 2) {
|
|
2306
|
+
const c0 = B64_LOOKUP[base64.charCodeAt(fullGroups)];
|
|
2307
|
+
const c1 = B64_LOOKUP[base64.charCodeAt(fullGroups + 1)];
|
|
2308
|
+
const bitmap = c0 << 18 | c1 << 12;
|
|
2309
|
+
bytes[byteIndex++] = bitmap >> 16 & 255;
|
|
2310
|
+
}
|
|
2324
2311
|
return bytes;
|
|
2325
2312
|
}
|
|
2326
2313
|
function nativeUint8ArrayToBase64(uint8Array) {
|
|
2327
2314
|
return uint8Array.toBase64();
|
|
2328
2315
|
}
|
|
2329
2316
|
function fallbackUint8ArrayToBase64(uint8Array) {
|
|
2330
|
-
|
|
2317
|
+
const len = uint8Array.length;
|
|
2318
|
+
const fullGroups = Math.floor(len / 3) * 3;
|
|
2331
2319
|
let result = "";
|
|
2332
|
-
for (let i = 0; i <
|
|
2320
|
+
for (let i = 0; i < fullGroups; i += 3) {
|
|
2333
2321
|
const byte1 = uint8Array[i];
|
|
2334
2322
|
const byte2 = uint8Array[i + 1];
|
|
2335
2323
|
const byte3 = uint8Array[i + 2];
|
|
2336
2324
|
const bitmap = byte1 << 16 | byte2 << 8 | byte3;
|
|
2337
|
-
result += BASE64_CHARS[bitmap >> 18 &
|
|
2325
|
+
result += BASE64_CHARS[bitmap >> 18 & SIX_BIT_MASK] + // bits 23–18 (top sextet)
|
|
2326
|
+
BASE64_CHARS[bitmap >> 12 & SIX_BIT_MASK] + // bits 17–12
|
|
2327
|
+
BASE64_CHARS[bitmap >> 6 & SIX_BIT_MASK] + // bits 11–6
|
|
2328
|
+
BASE64_CHARS[bitmap & SIX_BIT_MASK];
|
|
2329
|
+
}
|
|
2330
|
+
const remaining = len - fullGroups;
|
|
2331
|
+
if (remaining === 1) {
|
|
2332
|
+
const bitmap = uint8Array[fullGroups] << 16;
|
|
2333
|
+
result += BASE64_CHARS[bitmap >> 18 & SIX_BIT_MASK] + BASE64_CHARS[bitmap >> 12 & SIX_BIT_MASK] + "==";
|
|
2334
|
+
} else if (remaining === 2) {
|
|
2335
|
+
const bitmap = uint8Array[fullGroups] << 16 | uint8Array[fullGroups + 1] << 8;
|
|
2336
|
+
result += BASE64_CHARS[bitmap >> 18 & SIX_BIT_MASK] + BASE64_CHARS[bitmap >> 12 & SIX_BIT_MASK] + BASE64_CHARS[bitmap >> 6 & SIX_BIT_MASK] + "=";
|
|
2338
2337
|
}
|
|
2339
2338
|
return result;
|
|
2340
2339
|
}
|
|
@@ -2381,7 +2380,7 @@ function numberToFloat16Bits(value) {
|
|
|
2381
2380
|
}
|
|
2382
2381
|
return sign << 15 | expBiased << 10 | frac;
|
|
2383
2382
|
}
|
|
2384
|
-
var b64Vecs = class {
|
|
2383
|
+
var b64Vecs = class _b64Vecs {
|
|
2385
2384
|
/**
|
|
2386
2385
|
* Encode a single point (x, y, z) to 8 base64 characters using legacy Float16 encoding.
|
|
2387
2386
|
* Each coordinate is encoded as a Float16 value, resulting in 6 bytes total.
|
|
@@ -2455,10 +2454,12 @@ var b64Vecs = class {
|
|
|
2455
2454
|
* - Delta points: 3 Float16 values each = 6 bytes = 8 base64 chars each
|
|
2456
2455
|
*
|
|
2457
2456
|
* @param points - An array of VecModel objects to encode
|
|
2457
|
+
* @param dim - Encoding dimension; `2` routes through the 2D variant (drops z), `3` (default) keeps x, y, z
|
|
2458
2458
|
* @returns A base64-encoded string containing delta-encoded points
|
|
2459
2459
|
* @public
|
|
2460
2460
|
*/
|
|
2461
|
-
static encodePoints(points) {
|
|
2461
|
+
static encodePoints(points, dim) {
|
|
2462
|
+
if (dim === DIM_2D) return _b64Vecs.encodePoints2D(points);
|
|
2462
2463
|
if (points.length === 0) return "";
|
|
2463
2464
|
const firstPointBytes = 12;
|
|
2464
2465
|
const deltaBytes = (points.length - 1) * 6;
|
|
@@ -2491,10 +2492,12 @@ var b64Vecs = class {
|
|
|
2491
2492
|
* Float16 deltas that are accumulated to reconstruct absolute positions.
|
|
2492
2493
|
*
|
|
2493
2494
|
* @param base64 - The base64-encoded string containing delta-encoded point data
|
|
2495
|
+
* @param dim - Encoding dimension; `2` expects x/y only (z supplied as 0.5), `3` (default) expects x/y/z
|
|
2494
2496
|
* @returns An array of VecModel objects with absolute coordinates
|
|
2495
2497
|
* @public
|
|
2496
2498
|
*/
|
|
2497
|
-
static decodePoints(base64) {
|
|
2499
|
+
static decodePoints(base64, dim) {
|
|
2500
|
+
if (dim === DIM_2D) return _b64Vecs.decodePoints2D(base64);
|
|
2498
2501
|
if (base64.length === 0) return [];
|
|
2499
2502
|
const bytes = base64ToUint8Array(base64);
|
|
2500
2503
|
const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
@@ -2517,10 +2520,12 @@ var b64Vecs = class {
|
|
|
2517
2520
|
* The first point is stored as Float32 for full precision.
|
|
2518
2521
|
*
|
|
2519
2522
|
* @param b64Points - The delta-encoded base64 string
|
|
2523
|
+
* @param dim - Encoding dimension; `2` expects x/y only (z supplied as 0.5), `3` (default) expects x/y/z
|
|
2520
2524
|
* @returns The first point as a VecModel, or null if the string is too short
|
|
2521
2525
|
* @public
|
|
2522
2526
|
*/
|
|
2523
|
-
static decodeFirstPoint(b64Points) {
|
|
2527
|
+
static decodeFirstPoint(b64Points, dim) {
|
|
2528
|
+
if (dim === DIM_2D) return _b64Vecs.decodeFirstPoint2D(b64Points);
|
|
2524
2529
|
if (b64Points.length < FIRST_POINT_B64_LENGTH) return null;
|
|
2525
2530
|
const bytes = base64ToUint8Array(b64Points.slice(0, FIRST_POINT_B64_LENGTH));
|
|
2526
2531
|
const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
@@ -2535,10 +2540,12 @@ var b64Vecs = class {
|
|
|
2535
2540
|
* Requires decoding all points to accumulate deltas.
|
|
2536
2541
|
*
|
|
2537
2542
|
* @param b64Points - The delta-encoded base64 string
|
|
2543
|
+
* @param dim - Encoding dimension; `2` expects x/y only (z supplied as 0.5), `3` (default) expects x/y/z
|
|
2538
2544
|
* @returns The last point as a VecModel, or null if the string is too short
|
|
2539
2545
|
* @public
|
|
2540
2546
|
*/
|
|
2541
|
-
static decodeLastPoint(b64Points) {
|
|
2547
|
+
static decodeLastPoint(b64Points, dim) {
|
|
2548
|
+
if (dim === DIM_2D) return _b64Vecs.decodeLastPoint2D(b64Points);
|
|
2542
2549
|
if (b64Points.length < FIRST_POINT_B64_LENGTH) return null;
|
|
2543
2550
|
const bytes = base64ToUint8Array(b64Points);
|
|
2544
2551
|
const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
@@ -2553,12 +2560,129 @@ var b64Vecs = class {
|
|
|
2553
2560
|
}
|
|
2554
2561
|
return { x, y, z };
|
|
2555
2562
|
}
|
|
2563
|
+
/**
|
|
2564
|
+
* Encode an array of VecModels as 2D delta-encoded points, dropping z entirely.
|
|
2565
|
+
* Use for draw shapes from devices that don't report pressure, where z is a
|
|
2566
|
+
* constant 0.5 and storing it wastes ~33% of per-point bytes.
|
|
2567
|
+
*
|
|
2568
|
+
* Format:
|
|
2569
|
+
* - First point: 2 Float32 values (x, y) = 8 bytes
|
|
2570
|
+
* - Delta points: 2 Float16 values (dx, dy) = 4 bytes each
|
|
2571
|
+
*
|
|
2572
|
+
* @param points - An array of VecModel objects to encode (z is discarded)
|
|
2573
|
+
* @returns A base64-encoded string containing 2D delta-encoded points
|
|
2574
|
+
* @public
|
|
2575
|
+
*/
|
|
2576
|
+
static encodePoints2D(points) {
|
|
2577
|
+
if (points.length === 0) return "";
|
|
2578
|
+
const firstPointBytes = 8;
|
|
2579
|
+
const deltaBytes = (points.length - 1) * 4;
|
|
2580
|
+
const buffer = new Uint8Array(firstPointBytes + deltaBytes);
|
|
2581
|
+
const dataView = new DataView(buffer.buffer);
|
|
2582
|
+
const first = points[0];
|
|
2583
|
+
dataView.setFloat32(0, first.x, true);
|
|
2584
|
+
dataView.setFloat32(4, first.y, true);
|
|
2585
|
+
let prevX = first.x;
|
|
2586
|
+
let prevY = first.y;
|
|
2587
|
+
for (let i = 1; i < points.length; i++) {
|
|
2588
|
+
const p = points[i];
|
|
2589
|
+
const offset = firstPointBytes + (i - 1) * 4;
|
|
2590
|
+
setFloat16(dataView, offset, p.x - prevX);
|
|
2591
|
+
setFloat16(dataView, offset + 2, p.y - prevY);
|
|
2592
|
+
prevX = p.x;
|
|
2593
|
+
prevY = p.y;
|
|
2594
|
+
}
|
|
2595
|
+
return uint8ArrayToBase64(buffer);
|
|
2596
|
+
}
|
|
2597
|
+
/**
|
|
2598
|
+
* Decode a 2D delta-encoded base64 string back to an array of absolute VecModels.
|
|
2599
|
+
* The z coordinate is always set to 0.5 (the default pressure value) so downstream
|
|
2600
|
+
* consumers don't need a separate code path.
|
|
2601
|
+
*
|
|
2602
|
+
* @param base64 - The base64-encoded string containing 2D delta-encoded point data
|
|
2603
|
+
* @returns An array of VecModel objects with absolute (x, y) and z = 0.5
|
|
2604
|
+
* @public
|
|
2605
|
+
*/
|
|
2606
|
+
static decodePoints2D(base64) {
|
|
2607
|
+
if (base64.length === 0) return [];
|
|
2608
|
+
const bytes = base64ToUint8Array(base64);
|
|
2609
|
+
const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
2610
|
+
const result = [];
|
|
2611
|
+
let x = dataView.getFloat32(0, true);
|
|
2612
|
+
let y = dataView.getFloat32(4, true);
|
|
2613
|
+
result.push({ x, y, z: DEFAULT_PRESSURE });
|
|
2614
|
+
const firstPointBytes = 8;
|
|
2615
|
+
for (let offset = firstPointBytes; offset < bytes.length; offset += 4) {
|
|
2616
|
+
x += getFloat16(dataView, offset);
|
|
2617
|
+
y += getFloat16(dataView, offset + 2);
|
|
2618
|
+
result.push({ x, y, z: DEFAULT_PRESSURE });
|
|
2619
|
+
}
|
|
2620
|
+
return result;
|
|
2621
|
+
}
|
|
2622
|
+
/**
|
|
2623
|
+
* Get the first point from a 2D delta-encoded base64 string.
|
|
2624
|
+
*
|
|
2625
|
+
* @param b64Points - The 2D delta-encoded base64 string
|
|
2626
|
+
* @returns The first point with z = 0.5, or null if the string is too short
|
|
2627
|
+
* @public
|
|
2628
|
+
*/
|
|
2629
|
+
static decodeFirstPoint2D(b64Points) {
|
|
2630
|
+
if (b64Points.length < FIRST_POINT_2D_B64_LENGTH) return null;
|
|
2631
|
+
const bytes = base64ToUint8Array(b64Points.slice(0, FIRST_POINT_2D_B64_LENGTH));
|
|
2632
|
+
const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
2633
|
+
return {
|
|
2634
|
+
x: dataView.getFloat32(0, true),
|
|
2635
|
+
y: dataView.getFloat32(4, true),
|
|
2636
|
+
z: DEFAULT_PRESSURE
|
|
2637
|
+
};
|
|
2638
|
+
}
|
|
2639
|
+
/**
|
|
2640
|
+
* Get the last point from a 2D delta-encoded base64 string.
|
|
2641
|
+
* Requires decoding all points to accumulate deltas.
|
|
2642
|
+
*
|
|
2643
|
+
* @param b64Points - The 2D delta-encoded base64 string
|
|
2644
|
+
* @returns The last point with z = 0.5, or null if the string is too short
|
|
2645
|
+
* @public
|
|
2646
|
+
*/
|
|
2647
|
+
static decodeLastPoint2D(b64Points) {
|
|
2648
|
+
if (b64Points.length < FIRST_POINT_2D_B64_LENGTH) return null;
|
|
2649
|
+
const bytes = base64ToUint8Array(b64Points);
|
|
2650
|
+
const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
2651
|
+
let x = dataView.getFloat32(0, true);
|
|
2652
|
+
let y = dataView.getFloat32(4, true);
|
|
2653
|
+
const firstPointBytes = 8;
|
|
2654
|
+
for (let offset = firstPointBytes; offset < bytes.length; offset += 4) {
|
|
2655
|
+
x += getFloat16(dataView, offset);
|
|
2656
|
+
y += getFloat16(dataView, offset + 2);
|
|
2657
|
+
}
|
|
2658
|
+
return { x, y, z: DEFAULT_PRESSURE };
|
|
2659
|
+
}
|
|
2660
|
+
/**
|
|
2661
|
+
* Whether an encoded path contains only a single point (a "dot"), inferred from
|
|
2662
|
+
* the encoded length without decoding — cheap enough for the render path.
|
|
2663
|
+
*
|
|
2664
|
+
* The single-point length depends on the encoding dimension, so this takes the
|
|
2665
|
+
* segment's `dim`: a one-point path is `FIRST_POINT_B64_LENGTH` chars (3D) or
|
|
2666
|
+
* `FIRST_POINT_2D_B64_LENGTH` chars (2D). Keeping this beside the layout constants
|
|
2667
|
+
* is deliberate — it is the single source of truth for "how long is one point", so
|
|
2668
|
+
* callers never hard-code a length threshold (which silently breaks when a new
|
|
2669
|
+
* encoding is added).
|
|
2670
|
+
*
|
|
2671
|
+
* @param b64Points - The encoded path string
|
|
2672
|
+
* @param dim - Encoding dimension; `2` for (x, y), `3` (default) for (x, y, z)
|
|
2673
|
+
* @returns true if the path encodes exactly one point
|
|
2674
|
+
* @public
|
|
2675
|
+
*/
|
|
2676
|
+
static isSinglePoint(b64Points, dim) {
|
|
2677
|
+
return b64Points.length <= (dim === DIM_2D ? FIRST_POINT_2D_B64_LENGTH : FIRST_POINT_B64_LENGTH);
|
|
2678
|
+
}
|
|
2556
2679
|
};
|
|
2557
2680
|
|
|
2558
2681
|
// src/shapes/DrDrawShape.ts
|
|
2559
2682
|
var DrawShapeSegment = T.object({
|
|
2560
2683
|
type: T.literalEnum("free", "straight"),
|
|
2561
|
-
path: T.string
|
|
2684
|
+
path: T.string,
|
|
2685
|
+
dim: T.literalEnum(DIM_2D, DIM_3D).optional()
|
|
2562
2686
|
});
|
|
2563
2687
|
var drawShapeProps = {
|
|
2564
2688
|
color: DefaultColorStyle,
|
|
@@ -2577,7 +2701,8 @@ var Versions5 = createShapePropsMigrationIds("draw", {
|
|
|
2577
2701
|
AddInPen: 1,
|
|
2578
2702
|
AddScale: 2,
|
|
2579
2703
|
Base64: 3,
|
|
2580
|
-
LegacyPointsConversion: 4
|
|
2704
|
+
LegacyPointsConversion: 4,
|
|
2705
|
+
OmitNonPressureZ: 5
|
|
2581
2706
|
});
|
|
2582
2707
|
var drawShapeMigrations = createShapePropsMigrationSequence({
|
|
2583
2708
|
sequence: [
|
|
@@ -2648,6 +2773,18 @@ var drawShapeMigrations = createShapePropsMigrationSequence({
|
|
|
2648
2773
|
},
|
|
2649
2774
|
down: (_props) => {
|
|
2650
2775
|
}
|
|
2776
|
+
},
|
|
2777
|
+
{
|
|
2778
|
+
id: Versions5.OmitNonPressureZ,
|
|
2779
|
+
up: (_props) => {
|
|
2780
|
+
},
|
|
2781
|
+
down: (props) => {
|
|
2782
|
+
props.segments = props.segments.map((segment) => {
|
|
2783
|
+
if (segment.dim === void 0) return segment;
|
|
2784
|
+
const { dim, ...rest } = segment;
|
|
2785
|
+
return dim === DIM_2D ? { ...rest, path: b64Vecs.encodePoints(b64Vecs.decodePoints(segment.path, DIM_2D)) } : rest;
|
|
2786
|
+
});
|
|
2787
|
+
}
|
|
2651
2788
|
}
|
|
2652
2789
|
]
|
|
2653
2790
|
});
|
|
@@ -3168,7 +3305,8 @@ var highlightShapeProps = {
|
|
|
3168
3305
|
var Versions8 = createShapePropsMigrationIds("highlight", {
|
|
3169
3306
|
AddScale: 1,
|
|
3170
3307
|
Base64: 2,
|
|
3171
|
-
LegacyPointsConversion: 3
|
|
3308
|
+
LegacyPointsConversion: 3,
|
|
3309
|
+
OmitNonPressureZ: 4
|
|
3172
3310
|
});
|
|
3173
3311
|
var highlightShapeMigrations = createShapePropsMigrationSequence({
|
|
3174
3312
|
sequence: [
|
|
@@ -3223,6 +3361,18 @@ var highlightShapeMigrations = createShapePropsMigrationSequence({
|
|
|
3223
3361
|
},
|
|
3224
3362
|
down: (_props) => {
|
|
3225
3363
|
}
|
|
3364
|
+
},
|
|
3365
|
+
{
|
|
3366
|
+
id: Versions8.OmitNonPressureZ,
|
|
3367
|
+
up: (_props) => {
|
|
3368
|
+
},
|
|
3369
|
+
down: (props) => {
|
|
3370
|
+
props.segments = props.segments.map((segment) => {
|
|
3371
|
+
if (segment.dim === void 0) return segment;
|
|
3372
|
+
const { dim, ...rest } = segment;
|
|
3373
|
+
return dim === DIM_2D ? { ...rest, path: b64Vecs.encodePoints(b64Vecs.decodePoints(segment.path, DIM_2D)) } : rest;
|
|
3374
|
+
});
|
|
3375
|
+
}
|
|
3226
3376
|
}
|
|
3227
3377
|
]
|
|
3228
3378
|
});
|
|
@@ -3440,7 +3590,7 @@ var noteShapeProps = {
|
|
|
3440
3590
|
url: T.linkUrl,
|
|
3441
3591
|
richText: richTextValidator,
|
|
3442
3592
|
scale: T.nonZeroNumber,
|
|
3443
|
-
|
|
3593
|
+
textLastEditedBy: T.string.nullable()
|
|
3444
3594
|
};
|
|
3445
3595
|
var Versions10 = createShapePropsMigrationIds("note", {
|
|
3446
3596
|
AddUrlProp: 1,
|
|
@@ -3454,7 +3604,8 @@ var Versions10 = createShapePropsMigrationIds("note", {
|
|
|
3454
3604
|
AddRichText: 9,
|
|
3455
3605
|
AddRichTextAttrs: 10,
|
|
3456
3606
|
AddFirstEditedBy: 11,
|
|
3457
|
-
MakeFontSizeAdjustmentRatio: 12
|
|
3607
|
+
MakeFontSizeAdjustmentRatio: 12,
|
|
3608
|
+
RenameFirstEditedByToLast: 13
|
|
3458
3609
|
});
|
|
3459
3610
|
var noteShapeMigrations = createShapePropsMigrationSequence({
|
|
3460
3611
|
sequence: [
|
|
@@ -3573,6 +3724,17 @@ var noteShapeMigrations = createShapePropsMigrationSequence({
|
|
|
3573
3724
|
down: (props) => {
|
|
3574
3725
|
props.fontSizeAdjustment = 0;
|
|
3575
3726
|
}
|
|
3727
|
+
},
|
|
3728
|
+
{
|
|
3729
|
+
id: Versions10.RenameFirstEditedByToLast,
|
|
3730
|
+
up: (props) => {
|
|
3731
|
+
props.textLastEditedBy = props.textFirstEditedBy ?? null;
|
|
3732
|
+
delete props.textFirstEditedBy;
|
|
3733
|
+
},
|
|
3734
|
+
down: (props) => {
|
|
3735
|
+
props.textFirstEditedBy = props.textLastEditedBy ?? null;
|
|
3736
|
+
delete props.textLastEditedBy;
|
|
3737
|
+
}
|
|
3576
3738
|
}
|
|
3577
3739
|
]
|
|
3578
3740
|
});
|
|
@@ -3863,8 +4025,7 @@ function createIntegrityChecker(store) {
|
|
|
3863
4025
|
store.put([
|
|
3864
4026
|
store.schema.types.instance.create({
|
|
3865
4027
|
id: DrINSTANCE_ID,
|
|
3866
|
-
currentPageId: getFirstPageId()
|
|
3867
|
-
exportBackground: true
|
|
4028
|
+
currentPageId: getFirstPageId()
|
|
3868
4029
|
})
|
|
3869
4030
|
]);
|
|
3870
4031
|
return ensureStoreIsUsable();
|
|
@@ -4045,6 +4206,56 @@ function createDrSchema({
|
|
|
4045
4206
|
}
|
|
4046
4207
|
);
|
|
4047
4208
|
}
|
|
4209
|
+
function createPresenceStateDerivation($user, opts) {
|
|
4210
|
+
const { instanceId, getUserPresence: _getUserPresence } = opts ?? {};
|
|
4211
|
+
const getUserPresence = _getUserPresence ?? getDefaultUserPresence;
|
|
4212
|
+
return (store) => {
|
|
4213
|
+
return computed("instancePresence", () => {
|
|
4214
|
+
const user = $user.get();
|
|
4215
|
+
if (!user) return null;
|
|
4216
|
+
const state = getUserPresence(store, user);
|
|
4217
|
+
if (!state) return null;
|
|
4218
|
+
return InstancePresenceRecordType.create({
|
|
4219
|
+
...state,
|
|
4220
|
+
id: instanceId ?? InstancePresenceRecordType.createId(store.id)
|
|
4221
|
+
});
|
|
4222
|
+
});
|
|
4223
|
+
};
|
|
4224
|
+
}
|
|
4225
|
+
function getDefaultUserPresence(store, user) {
|
|
4226
|
+
const instance = store.get(DrINSTANCE_ID);
|
|
4227
|
+
const pageState = store.get(InstancePageStateRecordType.createId(instance?.currentPageId));
|
|
4228
|
+
const camera = store.get(CameraRecordType.createId(instance?.currentPageId));
|
|
4229
|
+
const pointer = store.get(DrPOINTER_ID);
|
|
4230
|
+
if (!pageState || !instance || !camera || !pointer) {
|
|
4231
|
+
return null;
|
|
4232
|
+
}
|
|
4233
|
+
return {
|
|
4234
|
+
selectedShapeIds: pageState.selectedShapeIds,
|
|
4235
|
+
brush: instance.brush,
|
|
4236
|
+
scribbles: instance.scribbles,
|
|
4237
|
+
userId: user.id,
|
|
4238
|
+
userName: user.name,
|
|
4239
|
+
followingUserId: instance.followingUserId,
|
|
4240
|
+
camera: {
|
|
4241
|
+
x: camera.x,
|
|
4242
|
+
y: camera.y,
|
|
4243
|
+
z: camera.z
|
|
4244
|
+
},
|
|
4245
|
+
color: user.color || "#FF0000",
|
|
4246
|
+
currentPageId: instance.currentPageId,
|
|
4247
|
+
cursor: {
|
|
4248
|
+
x: pointer.x,
|
|
4249
|
+
y: pointer.y,
|
|
4250
|
+
rotation: instance.cursor.rotation,
|
|
4251
|
+
type: instance.cursor.type
|
|
4252
|
+
},
|
|
4253
|
+
lastActivityTimestamp: pointer.lastActivityTimestamp,
|
|
4254
|
+
screenBounds: instance.screenBounds,
|
|
4255
|
+
chatMessage: instance.chatMessage,
|
|
4256
|
+
meta: {}
|
|
4257
|
+
};
|
|
4258
|
+
}
|
|
4048
4259
|
|
|
4049
4260
|
// src/misc/DrHandle.ts
|
|
4050
4261
|
var TL_HANDLE_TYPES = /* @__PURE__ */ new Set(["vertex", "virtual", "create", "clone"]);
|
|
@@ -4143,10 +4354,10 @@ function getSupportedLocale(locale) {
|
|
|
4143
4354
|
// src/index.ts
|
|
4144
4355
|
registerDrawLibraryVersion(
|
|
4145
4356
|
"@ibodr/schema",
|
|
4146
|
-
"0.2.
|
|
4357
|
+
"0.2.7",
|
|
4147
4358
|
"esm"
|
|
4148
4359
|
);
|
|
4149
4360
|
|
|
4150
|
-
export { ArrowShapeArrowheadEndStyle, ArrowShapeArrowheadStartStyle, ArrowShapeKindStyle, AssetRecordType, CameraRecordType, DR_BOARD_BACKGROUND_TYPES, DefaultColorStyle, DefaultDashStyle, DefaultFillStyle, DefaultFontFamilies, DefaultFontStyle, DefaultHorizontalAlignStyle, DefaultLabelColorStyle, DefaultSizeStyle, DefaultTextAlignStyle, DefaultVerticalAlignStyle, DocumentRecordType, DrDOCUMENT_ID, DrINSTANCE_ID, DrPOINTER_ID, ElbowArrowSnap, EnumStyleProp, GeoShapeGeoStyle, ImageShapeCrop, InstancePageStateRecordType, InstancePresenceRecordType, LANGUAGES, LineShapeSplineStyle, PageRecordType, PointerRecordType, StyleProp, TL_CANVAS_UI_COLOR_TYPES, TL_CURSOR_TYPES, TL_HANDLE_TYPES, TL_SCRIBBLE_STATES, UserRecordType, arrowBindingMigrations, arrowBindingProps, arrowBindingVersions, arrowShapeMigrations, arrowShapeProps, arrowShapeVersions, assetIdValidator, assetMigrations, b64Vecs, bindingIdValidator, bookmarkAssetMigrations, bookmarkAssetProps, bookmarkShapeMigrations, bookmarkShapeProps, boxModelValidator, canvasUiColorTypeValidator, compressLegacySegments, createAssetPropsMigrationIds, createAssetPropsMigrationSequence, createAssetRecordType, createAssetValidator, createBindingId, createBindingPropsMigrationIds, createBindingPropsMigrationSequence, createBindingValidator, createCachedUserResolve, createCustomRecordId, createCustomRecordMigrationIds, createCustomRecordMigrationSequence, createDrSchema, createPresenceStateDerivation, createShapeId, createShapePropsMigrationIds, createShapePropsMigrationSequence, createShapeValidator, createUserId, createUserRecordType, defaultAssetSchemas, defaultBindingSchemas, defaultShapeSchemas, drawShapeMigrations, drawShapeProps, embedShapeMigrations, embedShapeProps, frameShapeMigrations, frameShapeProps, geoShapeMigrations, geoShapeProps, getDefaultTranslationLocale, getDefaultUserPresence, getShapePropKeysByStyle, groupShapeMigrations, groupShapeProps, highlightShapeMigrations, highlightShapeProps, idValidator, imageAssetMigrations, imageAssetProps, imageShapeMigrations, imageShapeProps, isBinding, isBindingId, isCssHexColor, isCustomRecord, isCustomRecordId, isDocument, isFontEntry, isPageId, isShape, isShapeId, isUserId, lineShapeMigrations, lineShapeProps, noteShapeMigrations, noteShapeProps, opacityValidator, pageIdValidator, parentIdValidator, pluckPreservingValues, registerColorsFromThemes, registerFontsFromThemes, richTextValidator, rootBindingMigrations, rootShapeMigrations, scribbleValidator, shapeIdValidator, textShapeMigrations, textShapeProps, toRichText, userIdValidator, vecModelValidator, videoAssetMigrations, videoAssetProps, videoShapeMigrations, videoShapeProps };
|
|
4361
|
+
export { ArrowShapeArrowheadEndStyle, ArrowShapeArrowheadStartStyle, ArrowShapeKindStyle, AssetRecordType, CameraRecordType, DIM_2D, DIM_3D, DR_BOARD_BACKGROUND_TYPES, DefaultColorStyle, DefaultDashStyle, DefaultFillStyle, DefaultFontFamilies, DefaultFontStyle, DefaultHorizontalAlignStyle, DefaultLabelColorStyle, DefaultSizeStyle, DefaultTextAlignStyle, DefaultVerticalAlignStyle, DocumentRecordType, DrDOCUMENT_ID, DrINSTANCE_ID, DrPOINTER_ID, ElbowArrowSnap, EnumStyleProp, GeoShapeGeoStyle, ImageShapeCrop, InstancePageStateRecordType, InstancePresenceRecordType, LANGUAGES, LineShapeSplineStyle, PageRecordType, PointerRecordType, StyleProp, TL_CANVAS_UI_COLOR_TYPES, TL_CURSOR_TYPES, TL_HANDLE_TYPES, TL_SCRIBBLE_STATES, UserRecordType, arrowBindingMigrations, arrowBindingProps, arrowBindingVersions, arrowShapeMigrations, arrowShapeProps, arrowShapeVersions, assetIdValidator, assetMigrations, b64Vecs, bindingIdValidator, bookmarkAssetMigrations, bookmarkAssetProps, bookmarkShapeMigrations, bookmarkShapeProps, boxModelValidator, canvasUiColorTypeValidator, compressLegacySegments, createAssetPropsMigrationIds, createAssetPropsMigrationSequence, createAssetRecordType, createAssetValidator, createBindingId, createBindingPropsMigrationIds, createBindingPropsMigrationSequence, createBindingValidator, createCachedUserResolve, createCustomRecordId, createCustomRecordMigrationIds, createCustomRecordMigrationSequence, createDrSchema, createPresenceStateDerivation, createShapeId, createShapePropsMigrationIds, createShapePropsMigrationSequence, createShapeValidator, createUserId, createUserRecordType, defaultAssetSchemas, defaultBindingSchemas, defaultShapeSchemas, drawShapeMigrations, drawShapeProps, embedShapeMigrations, embedShapeProps, frameShapeMigrations, frameShapeProps, geoShapeMigrations, geoShapeProps, getDefaultTranslationLocale, getDefaultUserPresence, getShapePropKeysByStyle, groupShapeMigrations, groupShapeProps, highlightShapeMigrations, highlightShapeProps, idValidator, imageAssetMigrations, imageAssetProps, imageShapeMigrations, imageShapeProps, isBinding, isBindingId, isCssHexColor, isCustomRecord, isCustomRecordId, isDocument, isFontEntry, isPage, isPageId, isShape, isShapeId, isUserId, lineShapeMigrations, lineShapeProps, noteShapeMigrations, noteShapeProps, opacityValidator, pageIdValidator, parentIdValidator, pluckPreservingValues, registerColorsFromThemes, registerFontsFromThemes, richTextValidator, rootBindingMigrations, rootShapeMigrations, scribbleValidator, shapeIdValidator, textShapeMigrations, textShapeProps, toRichText, userIdValidator, vecModelValidator, videoAssetMigrations, videoAssetProps, videoShapeMigrations, videoShapeProps };
|
|
4151
4362
|
//# sourceMappingURL=index.mjs.map
|
|
4152
4363
|
//# sourceMappingURL=index.mjs.map
|