@woven-canvas/core 0.1.4 → 1.0.1
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/build/_tsup-dts-rollup.d.cts +55 -4
- package/build/_tsup-dts-rollup.d.ts +55 -4
- package/build/index.cjs +533 -277
- package/build/index.cjs.map +1 -1
- package/build/index.d.cts +6 -0
- package/build/index.d.ts +6 -0
- package/build/index.js +405 -155
- package/build/index.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
package/build/index.js
CHANGED
|
@@ -8,7 +8,7 @@ var __export = (target, all) => {
|
|
|
8
8
|
import {
|
|
9
9
|
CanvasComponentDef as CanvasComponentDef7,
|
|
10
10
|
CanvasSingletonDef as CanvasSingletonDef12,
|
|
11
|
-
defineCanvasComponent as
|
|
11
|
+
defineCanvasComponent as defineCanvasComponent14,
|
|
12
12
|
defineCanvasSingleton as defineCanvasSingleton3,
|
|
13
13
|
Synced as Synced4
|
|
14
14
|
} from "@woven-ecs/canvas-store";
|
|
@@ -19,9 +19,9 @@ import {
|
|
|
19
19
|
defineQuery as defineQuery11,
|
|
20
20
|
defineSystem,
|
|
21
21
|
EventType,
|
|
22
|
-
field as
|
|
22
|
+
field as field29,
|
|
23
23
|
getBackrefs,
|
|
24
|
-
getResources as
|
|
24
|
+
getResources as getResources13,
|
|
25
25
|
hasComponent as hasComponent7,
|
|
26
26
|
isAlive,
|
|
27
27
|
MainThreadSystem as MainThreadSystem2,
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
CanvasComponentDef as CanvasComponentDef6,
|
|
36
36
|
CanvasSingletonDef as CanvasSingletonDef10
|
|
37
37
|
} from "@woven-ecs/canvas-store";
|
|
38
|
-
import { getResources as
|
|
38
|
+
import { getResources as getResources12 } from "@woven-ecs/core";
|
|
39
39
|
|
|
40
40
|
// src/components/index.ts
|
|
41
41
|
var components_exports = {};
|
|
@@ -46,6 +46,8 @@ __export(components_exports, {
|
|
|
46
46
|
Color: () => Color,
|
|
47
47
|
Connector: () => Connector,
|
|
48
48
|
Edited: () => Edited,
|
|
49
|
+
Embed: () => Embed,
|
|
50
|
+
EmbedProvider: () => EmbedProvider,
|
|
49
51
|
Held: () => Held,
|
|
50
52
|
HitGeometry: () => HitGeometry,
|
|
51
53
|
Hovered: () => Hovered,
|
|
@@ -325,6 +327,7 @@ var BlockDef = z.object({
|
|
|
325
327
|
resizeMode: z.enum([ResizeMode.Scale, ResizeMode.Text, ResizeMode.Free, ResizeMode.GroupOnly]).default(ResizeMode.Scale),
|
|
326
328
|
canRotate: z.boolean().default(true),
|
|
327
329
|
canScale: z.boolean().default(true),
|
|
330
|
+
selectable: z.boolean().default(true),
|
|
328
331
|
connectors: BlockDefConnectors.default(BlockDefConnectors.parse({}))
|
|
329
332
|
});
|
|
330
333
|
|
|
@@ -721,30 +724,57 @@ var Connector = defineCanvasComponent2(
|
|
|
721
724
|
import { defineCanvasComponent as defineCanvasComponent3 } from "@woven-ecs/canvas-store";
|
|
722
725
|
var Edited = defineCanvasComponent3({ name: "edited" }, {});
|
|
723
726
|
|
|
724
|
-
// src/components/
|
|
727
|
+
// src/components/Embed.ts
|
|
725
728
|
import { defineCanvasComponent as defineCanvasComponent4 } from "@woven-ecs/canvas-store";
|
|
726
729
|
import { field as field6 } from "@woven-ecs/core";
|
|
727
|
-
var
|
|
730
|
+
var EmbedProvider = /* @__PURE__ */ ((EmbedProvider2) => {
|
|
731
|
+
EmbedProvider2["GoogleMaps"] = "google-maps";
|
|
732
|
+
EmbedProvider2["GoogleCalendar"] = "google-calendar";
|
|
733
|
+
EmbedProvider2["GoogleSlides"] = "google-slides";
|
|
734
|
+
EmbedProvider2["Tldraw"] = "tldraw";
|
|
735
|
+
EmbedProvider2["Figma"] = "figma";
|
|
736
|
+
EmbedProvider2["GithubGist"] = "github-gist";
|
|
737
|
+
EmbedProvider2["Youtube"] = "youtube";
|
|
738
|
+
EmbedProvider2["Spotify"] = "spotify";
|
|
739
|
+
EmbedProvider2["Unknown"] = "unknown";
|
|
740
|
+
return EmbedProvider2;
|
|
741
|
+
})(EmbedProvider || {});
|
|
742
|
+
var Embed = defineCanvasComponent4(
|
|
743
|
+
{ name: "embed", sync: "document" },
|
|
744
|
+
{
|
|
745
|
+
/** The original URL provided by the user */
|
|
746
|
+
url: field6.string().max(2048).default(""),
|
|
747
|
+
/** The resolved embed/iframe URL */
|
|
748
|
+
embedUrl: field6.string().max(2048).default(""),
|
|
749
|
+
/** The embed provider (used for provider-specific styling/behavior) */
|
|
750
|
+
provider: field6.enum(EmbedProvider).default("unknown" /* Unknown */)
|
|
751
|
+
}
|
|
752
|
+
);
|
|
753
|
+
|
|
754
|
+
// src/components/Held.ts
|
|
755
|
+
import { defineCanvasComponent as defineCanvasComponent5 } from "@woven-ecs/canvas-store";
|
|
756
|
+
import { field as field7 } from "@woven-ecs/core";
|
|
757
|
+
var Held = defineCanvasComponent5(
|
|
728
758
|
{ name: "held", sync: "ephemeral" },
|
|
729
759
|
{
|
|
730
|
-
sessionId:
|
|
760
|
+
sessionId: field7.string().max(36).default("")
|
|
731
761
|
}
|
|
732
762
|
);
|
|
733
763
|
|
|
734
764
|
// src/components/HitGeometry.ts
|
|
735
765
|
import { Arc, Capsule, Mat2 } from "@woven-canvas/math";
|
|
736
766
|
import { CanvasComponentDef as CanvasComponentDef4 } from "@woven-ecs/canvas-store";
|
|
737
|
-
import { field as
|
|
767
|
+
import { field as field8 } from "@woven-ecs/core";
|
|
738
768
|
var _uvToWorldMatrix = [1, 0, 0, 1, 0, 0];
|
|
739
769
|
var MAX_HIT_CAPSULES = 64;
|
|
740
770
|
var FLOATS_PER_CAPSULE = 5;
|
|
741
771
|
var MAX_HIT_ARCS = 2;
|
|
742
772
|
var FLOATS_PER_ARC = 7;
|
|
743
773
|
var HitGeometrySchema = {
|
|
744
|
-
hitCapsules:
|
|
745
|
-
capsuleCount:
|
|
746
|
-
hitArcs:
|
|
747
|
-
arcCount:
|
|
774
|
+
hitCapsules: field8.buffer(field8.float32()).size(MAX_HIT_CAPSULES * FLOATS_PER_CAPSULE),
|
|
775
|
+
capsuleCount: field8.uint16().default(0),
|
|
776
|
+
hitArcs: field8.buffer(field8.float32()).size(MAX_HIT_ARCS * FLOATS_PER_ARC),
|
|
777
|
+
arcCount: field8.uint16().default(0)
|
|
748
778
|
};
|
|
749
779
|
var HitGeometryDef = class extends CanvasComponentDef4 {
|
|
750
780
|
constructor() {
|
|
@@ -1050,37 +1080,37 @@ var HitGeometryDef = class extends CanvasComponentDef4 {
|
|
|
1050
1080
|
var HitGeometry = new HitGeometryDef();
|
|
1051
1081
|
|
|
1052
1082
|
// src/components/Hovered.ts
|
|
1053
|
-
import { defineCanvasComponent as
|
|
1054
|
-
var Hovered =
|
|
1083
|
+
import { defineCanvasComponent as defineCanvasComponent6 } from "@woven-ecs/canvas-store";
|
|
1084
|
+
var Hovered = defineCanvasComponent6({ name: "hovered" }, {});
|
|
1055
1085
|
|
|
1056
1086
|
// src/components/Image.ts
|
|
1057
|
-
import { defineCanvasComponent as
|
|
1058
|
-
import { field as
|
|
1059
|
-
var Image =
|
|
1087
|
+
import { defineCanvasComponent as defineCanvasComponent7 } from "@woven-ecs/canvas-store";
|
|
1088
|
+
import { field as field9 } from "@woven-ecs/core";
|
|
1089
|
+
var Image = defineCanvasComponent7(
|
|
1060
1090
|
{ name: "image", sync: "document" },
|
|
1061
1091
|
{
|
|
1062
1092
|
/** Image width in pixels */
|
|
1063
|
-
width:
|
|
1093
|
+
width: field9.uint16().default(0),
|
|
1064
1094
|
/** Image height in pixels */
|
|
1065
|
-
height:
|
|
1095
|
+
height: field9.uint16().default(0),
|
|
1066
1096
|
/** Alt text for accessibility */
|
|
1067
|
-
alt:
|
|
1097
|
+
alt: field9.string().max(256).default("")
|
|
1068
1098
|
}
|
|
1069
1099
|
);
|
|
1070
1100
|
|
|
1071
1101
|
// src/components/Opacity.ts
|
|
1072
|
-
import { defineCanvasComponent as
|
|
1073
|
-
import { field as
|
|
1074
|
-
var Opacity =
|
|
1102
|
+
import { defineCanvasComponent as defineCanvasComponent8 } from "@woven-ecs/canvas-store";
|
|
1103
|
+
import { field as field10 } from "@woven-ecs/core";
|
|
1104
|
+
var Opacity = defineCanvasComponent8(
|
|
1075
1105
|
{ name: "opacity" },
|
|
1076
1106
|
{
|
|
1077
|
-
value:
|
|
1107
|
+
value: field10.uint8().default(255)
|
|
1078
1108
|
}
|
|
1079
1109
|
);
|
|
1080
1110
|
|
|
1081
1111
|
// src/components/Pointer.ts
|
|
1082
1112
|
import { CanvasComponentDef as CanvasComponentDef5 } from "@woven-ecs/canvas-store";
|
|
1083
|
-
import { field as
|
|
1113
|
+
import { field as field11 } from "@woven-ecs/core";
|
|
1084
1114
|
var PointerButton = {
|
|
1085
1115
|
None: "none",
|
|
1086
1116
|
Left: "left",
|
|
@@ -1097,30 +1127,30 @@ var PointerType = {
|
|
|
1097
1127
|
var SAMPLE_COUNT = 6;
|
|
1098
1128
|
var PointerSchema = {
|
|
1099
1129
|
/** Unique pointer ID (from PointerEvent.pointerId) */
|
|
1100
|
-
pointerId:
|
|
1130
|
+
pointerId: field11.uint16().default(0),
|
|
1101
1131
|
/** Current position relative to the editor element [x, y] */
|
|
1102
|
-
position:
|
|
1132
|
+
position: field11.tuple(field11.float32(), 2).default([0, 0]),
|
|
1103
1133
|
/** Position where the pointer went down [x, y] */
|
|
1104
|
-
downPosition:
|
|
1134
|
+
downPosition: field11.tuple(field11.float32(), 2).default([0, 0]),
|
|
1105
1135
|
/** Frame number when the pointer went down (for click detection) */
|
|
1106
|
-
downFrame:
|
|
1136
|
+
downFrame: field11.uint32().default(0),
|
|
1107
1137
|
/** Which button is pressed */
|
|
1108
|
-
button:
|
|
1138
|
+
button: field11.enum(PointerButton).default(PointerButton.None),
|
|
1109
1139
|
/** Type of pointer device */
|
|
1110
|
-
pointerType:
|
|
1140
|
+
pointerType: field11.enum(PointerType).default(PointerType.Mouse),
|
|
1111
1141
|
/** Pressure from 0 to 1 (for pen/touch) */
|
|
1112
|
-
pressure:
|
|
1142
|
+
pressure: field11.float32().default(0),
|
|
1113
1143
|
/** Whether the pointer event target was not the editor element */
|
|
1114
|
-
obscured:
|
|
1144
|
+
obscured: field11.boolean().default(false),
|
|
1115
1145
|
// Velocity tracking (ring buffer for position samples)
|
|
1116
1146
|
/** Ring buffer of previous positions [x0, y0, x1, y1, ...] @internal */
|
|
1117
|
-
_prevPositions:
|
|
1147
|
+
_prevPositions: field11.array(field11.float32(), SAMPLE_COUNT * 2),
|
|
1118
1148
|
/** Ring buffer of timestamps for each position sample @internal */
|
|
1119
|
-
_prevTimes:
|
|
1149
|
+
_prevTimes: field11.array(field11.float32(), SAMPLE_COUNT),
|
|
1120
1150
|
/** Total number of samples added (used for ring buffer indexing) @internal */
|
|
1121
|
-
_sampleCount:
|
|
1151
|
+
_sampleCount: field11.int32().default(0),
|
|
1122
1152
|
/** Computed velocity [vx, vy] in pixels per second @internal */
|
|
1123
|
-
_velocity:
|
|
1153
|
+
_velocity: field11.tuple(field11.float32(), 2).default([0, 0])
|
|
1124
1154
|
};
|
|
1125
1155
|
var PointerDef = class extends CanvasComponentDef5 {
|
|
1126
1156
|
constructor() {
|
|
@@ -1231,108 +1261,108 @@ function addPointerSample(pointer, position, time) {
|
|
|
1231
1261
|
}
|
|
1232
1262
|
|
|
1233
1263
|
// src/components/ScaleWithZoom.ts
|
|
1234
|
-
import { defineCanvasComponent as
|
|
1235
|
-
import { field as
|
|
1236
|
-
var ScaleWithZoom =
|
|
1264
|
+
import { defineCanvasComponent as defineCanvasComponent9 } from "@woven-ecs/canvas-store";
|
|
1265
|
+
import { field as field12 } from "@woven-ecs/core";
|
|
1266
|
+
var ScaleWithZoom = defineCanvasComponent9(
|
|
1237
1267
|
{ name: "scaleWithZoom" },
|
|
1238
1268
|
{
|
|
1239
1269
|
/** Pivot point for scaling as [x, y] (0-1, default 0.5,0.5 = center) */
|
|
1240
|
-
anchor:
|
|
1270
|
+
anchor: field12.tuple(field12.float64(), 2).default([0.5, 0.5]),
|
|
1241
1271
|
/** Initial position as [left, top] at zoom=1 */
|
|
1242
|
-
startPosition:
|
|
1272
|
+
startPosition: field12.tuple(field12.float64(), 2).default([0, 0]),
|
|
1243
1273
|
/** Initial size as [width, height] at zoom=1 */
|
|
1244
|
-
startSize:
|
|
1274
|
+
startSize: field12.tuple(field12.float64(), 2).default([0, 0]),
|
|
1245
1275
|
/** Scale multiplier per dimension: [x, y] (0 = no zoom effect, 1 = full zoom effect, 0.5 = half effect) */
|
|
1246
|
-
scaleMultiplier:
|
|
1276
|
+
scaleMultiplier: field12.tuple(field12.float64(), 2).default([1, 1])
|
|
1247
1277
|
}
|
|
1248
1278
|
);
|
|
1249
1279
|
|
|
1250
1280
|
// src/components/Shape.ts
|
|
1251
|
-
import { defineCanvasComponent as
|
|
1252
|
-
import { field as
|
|
1281
|
+
import { defineCanvasComponent as defineCanvasComponent10 } from "@woven-ecs/canvas-store";
|
|
1282
|
+
import { field as field13 } from "@woven-ecs/core";
|
|
1253
1283
|
var StrokeKind = {
|
|
1254
1284
|
Solid: "solid",
|
|
1255
1285
|
Dashed: "dashed",
|
|
1256
1286
|
None: "none"
|
|
1257
1287
|
};
|
|
1258
|
-
var Shape =
|
|
1288
|
+
var Shape = defineCanvasComponent10(
|
|
1259
1289
|
{ name: "shape", sync: "document" },
|
|
1260
1290
|
{
|
|
1261
1291
|
/** The kind of shape to render (e.g. 'rectangle', 'ellipse', or custom shape key) */
|
|
1262
|
-
kind:
|
|
1292
|
+
kind: field13.string().default("rectangle"),
|
|
1263
1293
|
/** Stroke style */
|
|
1264
|
-
strokeKind:
|
|
1294
|
+
strokeKind: field13.enum(StrokeKind).default(StrokeKind.Solid),
|
|
1265
1295
|
/** Stroke width in pixels */
|
|
1266
|
-
strokeWidth:
|
|
1296
|
+
strokeWidth: field13.uint16().default(2),
|
|
1267
1297
|
/** Stroke color - red component (0-255) */
|
|
1268
|
-
strokeRed:
|
|
1298
|
+
strokeRed: field13.uint8().default(0),
|
|
1269
1299
|
/** Stroke color - green component (0-255) */
|
|
1270
|
-
strokeGreen:
|
|
1300
|
+
strokeGreen: field13.uint8().default(0),
|
|
1271
1301
|
/** Stroke color - blue component (0-255) */
|
|
1272
|
-
strokeBlue:
|
|
1302
|
+
strokeBlue: field13.uint8().default(0),
|
|
1273
1303
|
/** Stroke color - alpha component (0-255) */
|
|
1274
|
-
strokeAlpha:
|
|
1304
|
+
strokeAlpha: field13.uint8().default(255),
|
|
1275
1305
|
/** Fill color - red component (0-255) */
|
|
1276
|
-
fillRed:
|
|
1306
|
+
fillRed: field13.uint8().default(255),
|
|
1277
1307
|
/** Fill color - green component (0-255) */
|
|
1278
|
-
fillGreen:
|
|
1308
|
+
fillGreen: field13.uint8().default(255),
|
|
1279
1309
|
/** Fill color - blue component (0-255) */
|
|
1280
|
-
fillBlue:
|
|
1310
|
+
fillBlue: field13.uint8().default(255),
|
|
1281
1311
|
/** Fill color - alpha component (0-255) */
|
|
1282
|
-
fillAlpha:
|
|
1312
|
+
fillAlpha: field13.uint8().default(0)
|
|
1283
1313
|
}
|
|
1284
1314
|
);
|
|
1285
1315
|
|
|
1286
1316
|
// src/components/Text.ts
|
|
1287
|
-
import { defineCanvasComponent as
|
|
1288
|
-
import { field as
|
|
1289
|
-
var Text =
|
|
1317
|
+
import { defineCanvasComponent as defineCanvasComponent11 } from "@woven-ecs/canvas-store";
|
|
1318
|
+
import { field as field14 } from "@woven-ecs/core";
|
|
1319
|
+
var Text = defineCanvasComponent11(
|
|
1290
1320
|
{ name: "text", sync: "document" },
|
|
1291
1321
|
{
|
|
1292
1322
|
/** HTML content (supports rich text formatting) */
|
|
1293
|
-
content:
|
|
1323
|
+
content: field14.string().max(1e4).default(""),
|
|
1294
1324
|
/** Font size in pixels */
|
|
1295
|
-
fontSizePx:
|
|
1325
|
+
fontSizePx: field14.float64().default(24),
|
|
1296
1326
|
/** Font family name */
|
|
1297
|
-
fontFamily:
|
|
1327
|
+
fontFamily: field14.string().max(64).default("Figtree"),
|
|
1298
1328
|
/** Line height multiplier */
|
|
1299
|
-
lineHeight:
|
|
1329
|
+
lineHeight: field14.float64().default(1.2),
|
|
1300
1330
|
/** Letter spacing in em units */
|
|
1301
|
-
letterSpacingEm:
|
|
1331
|
+
letterSpacingEm: field14.float64().default(0),
|
|
1302
1332
|
/** Whether width is constrained (text wraps) */
|
|
1303
|
-
constrainWidth:
|
|
1333
|
+
constrainWidth: field14.boolean().default(true),
|
|
1304
1334
|
/** Default text alignment for new paragraphs */
|
|
1305
|
-
defaultAlignment:
|
|
1335
|
+
defaultAlignment: field14.enum(TextAlignment).default(TextAlignment.Left)
|
|
1306
1336
|
}
|
|
1307
1337
|
);
|
|
1308
1338
|
|
|
1309
1339
|
// src/components/User.ts
|
|
1310
|
-
import { defineCanvasComponent as
|
|
1311
|
-
import { field as
|
|
1312
|
-
var User =
|
|
1340
|
+
import { defineCanvasComponent as defineCanvasComponent12 } from "@woven-ecs/canvas-store";
|
|
1341
|
+
import { field as field15 } from "@woven-ecs/core";
|
|
1342
|
+
var User = defineCanvasComponent12(
|
|
1313
1343
|
{ name: "user", sync: "ephemeral" },
|
|
1314
1344
|
{
|
|
1315
|
-
userId:
|
|
1316
|
-
sessionId:
|
|
1317
|
-
color:
|
|
1318
|
-
name:
|
|
1319
|
-
avatar:
|
|
1320
|
-
position:
|
|
1345
|
+
userId: field15.string().max(36),
|
|
1346
|
+
sessionId: field15.string().max(36),
|
|
1347
|
+
color: field15.string().max(7),
|
|
1348
|
+
name: field15.string().max(100),
|
|
1349
|
+
avatar: field15.string().max(500),
|
|
1350
|
+
position: field15.tuple(field15.float32(), 2).default([0, 0])
|
|
1321
1351
|
}
|
|
1322
1352
|
);
|
|
1323
1353
|
|
|
1324
1354
|
// src/components/VerticalAlign.ts
|
|
1325
|
-
import { defineCanvasComponent as
|
|
1326
|
-
import { field as
|
|
1327
|
-
var VerticalAlign =
|
|
1355
|
+
import { defineCanvasComponent as defineCanvasComponent13 } from "@woven-ecs/canvas-store";
|
|
1356
|
+
import { field as field16 } from "@woven-ecs/core";
|
|
1357
|
+
var VerticalAlign = defineCanvasComponent13(
|
|
1328
1358
|
{ name: "verticalAlign", sync: "document" },
|
|
1329
1359
|
{
|
|
1330
|
-
value:
|
|
1360
|
+
value: field16.enum(VerticalAlignment).default(VerticalAlignment.Top)
|
|
1331
1361
|
}
|
|
1332
1362
|
);
|
|
1333
1363
|
|
|
1334
1364
|
// src/constants.ts
|
|
1335
|
-
var
|
|
1365
|
+
var CORE_PLUGIN_NAME = "core";
|
|
1336
1366
|
var STRATUM_ORDER = {
|
|
1337
1367
|
background: 0,
|
|
1338
1368
|
content: 1,
|
|
@@ -1361,20 +1391,20 @@ __export(singletons_exports, {
|
|
|
1361
1391
|
|
|
1362
1392
|
// src/singletons/Camera.ts
|
|
1363
1393
|
import { CanvasSingletonDef as CanvasSingletonDef2 } from "@woven-ecs/canvas-store";
|
|
1364
|
-
import { field as
|
|
1394
|
+
import { field as field18 } from "@woven-ecs/core";
|
|
1365
1395
|
|
|
1366
1396
|
// src/singletons/Screen.ts
|
|
1367
1397
|
import { CanvasSingletonDef } from "@woven-ecs/canvas-store";
|
|
1368
|
-
import { field as
|
|
1398
|
+
import { field as field17 } from "@woven-ecs/core";
|
|
1369
1399
|
var ScreenSchema = {
|
|
1370
1400
|
/** Width of the editor element in pixels */
|
|
1371
|
-
width:
|
|
1401
|
+
width: field17.float64().default(0),
|
|
1372
1402
|
/** Height of the editor element in pixels */
|
|
1373
|
-
height:
|
|
1403
|
+
height: field17.float64().default(0),
|
|
1374
1404
|
/** Left offset of the editor element relative to the viewport */
|
|
1375
|
-
left:
|
|
1405
|
+
left: field17.float64().default(0),
|
|
1376
1406
|
/** Top offset of the editor element relative to the viewport */
|
|
1377
|
-
top:
|
|
1407
|
+
top: field17.float64().default(0)
|
|
1378
1408
|
};
|
|
1379
1409
|
var ScreenDef = class extends CanvasSingletonDef {
|
|
1380
1410
|
constructor() {
|
|
@@ -1401,15 +1431,15 @@ var Screen = new ScreenDef();
|
|
|
1401
1431
|
// src/singletons/Camera.ts
|
|
1402
1432
|
var CameraSchema = {
|
|
1403
1433
|
/** Top position of the camera in world coordinates */
|
|
1404
|
-
top:
|
|
1434
|
+
top: field18.float64().default(0),
|
|
1405
1435
|
/** Left position of the camera in world coordinates */
|
|
1406
|
-
left:
|
|
1436
|
+
left: field18.float64().default(0),
|
|
1407
1437
|
/** Zoom level (1 = 100%, 2 = 200%, 0.5 = 50%) */
|
|
1408
|
-
zoom:
|
|
1438
|
+
zoom: field18.float64().default(1),
|
|
1409
1439
|
/** Whether the camera viewport intersects any blocks */
|
|
1410
|
-
canSeeBlocks:
|
|
1440
|
+
canSeeBlocks: field18.boolean().default(true),
|
|
1411
1441
|
/** Reference to a block that the camera can currently see (for optimization) */
|
|
1412
|
-
lastSeenBlock:
|
|
1442
|
+
lastSeenBlock: field18.ref()
|
|
1413
1443
|
};
|
|
1414
1444
|
var CameraDef = class extends CanvasSingletonDef2 {
|
|
1415
1445
|
constructor() {
|
|
@@ -1485,20 +1515,20 @@ var Camera = new CameraDef();
|
|
|
1485
1515
|
|
|
1486
1516
|
// src/singletons/Controls.ts
|
|
1487
1517
|
import { CanvasSingletonDef as CanvasSingletonDef3 } from "@woven-ecs/canvas-store";
|
|
1488
|
-
import { field as
|
|
1518
|
+
import { field as field19 } from "@woven-ecs/core";
|
|
1489
1519
|
var ControlsSchema = {
|
|
1490
1520
|
/** Tool activated by left mouse button */
|
|
1491
|
-
leftMouseTool:
|
|
1521
|
+
leftMouseTool: field19.string().max(32).default("select"),
|
|
1492
1522
|
/** Tool activated by middle mouse button */
|
|
1493
|
-
middleMouseTool:
|
|
1523
|
+
middleMouseTool: field19.string().max(32).default("hand"),
|
|
1494
1524
|
/** Tool activated by right mouse button */
|
|
1495
|
-
rightMouseTool:
|
|
1525
|
+
rightMouseTool: field19.string().max(32).default("menu"),
|
|
1496
1526
|
/** Tool activated by mouse wheel */
|
|
1497
|
-
wheelTool:
|
|
1527
|
+
wheelTool: field19.string().max(32).default("scroll"),
|
|
1498
1528
|
/** Tool activated by mouse wheel with modifier key held */
|
|
1499
|
-
modWheelTool:
|
|
1529
|
+
modWheelTool: field19.string().max(32).default("zoom"),
|
|
1500
1530
|
/** JSON snapshot of block to place on next click (empty string = no placement active) */
|
|
1501
|
-
heldSnapshot:
|
|
1531
|
+
heldSnapshot: field19.string().max(65536).default("")
|
|
1502
1532
|
};
|
|
1503
1533
|
var ControlsDef = class extends CanvasSingletonDef3 {
|
|
1504
1534
|
constructor() {
|
|
@@ -1540,16 +1570,16 @@ var Controls = new ControlsDef();
|
|
|
1540
1570
|
|
|
1541
1571
|
// src/singletons/Cursor.ts
|
|
1542
1572
|
import { CanvasSingletonDef as CanvasSingletonDef4 } from "@woven-ecs/canvas-store";
|
|
1543
|
-
import { field as
|
|
1573
|
+
import { field as field20 } from "@woven-ecs/core";
|
|
1544
1574
|
var CursorSchema = {
|
|
1545
1575
|
/** Base cursor kind (from current tool) */
|
|
1546
|
-
cursorKind:
|
|
1576
|
+
cursorKind: field20.string().max(64).default("select"),
|
|
1547
1577
|
/** Base cursor rotation in radians */
|
|
1548
|
-
rotation:
|
|
1578
|
+
rotation: field20.float64().default(0),
|
|
1549
1579
|
/** Context-specific cursor kind (overrides cursorKind when set, e.g., during drag/hover) */
|
|
1550
|
-
contextCursorKind:
|
|
1580
|
+
contextCursorKind: field20.string().max(64).default(""),
|
|
1551
1581
|
/** Context cursor rotation in radians */
|
|
1552
|
-
contextRotation:
|
|
1582
|
+
contextRotation: field20.float64().default(0)
|
|
1553
1583
|
};
|
|
1554
1584
|
var CursorDef2 = class extends CanvasSingletonDef4 {
|
|
1555
1585
|
constructor() {
|
|
@@ -1597,37 +1627,37 @@ var Cursor = new CursorDef2();
|
|
|
1597
1627
|
|
|
1598
1628
|
// src/singletons/Frame.ts
|
|
1599
1629
|
import { defineCanvasSingleton } from "@woven-ecs/canvas-store";
|
|
1600
|
-
import { field as
|
|
1630
|
+
import { field as field21 } from "@woven-ecs/core";
|
|
1601
1631
|
var Frame = defineCanvasSingleton(
|
|
1602
1632
|
{ name: "frame" },
|
|
1603
1633
|
{
|
|
1604
1634
|
/** Current frame number (increments each tick) */
|
|
1605
|
-
number:
|
|
1635
|
+
number: field21.uint32().default(0),
|
|
1606
1636
|
/** Time since last frame in seconds */
|
|
1607
|
-
delta:
|
|
1637
|
+
delta: field21.float64().default(0),
|
|
1608
1638
|
/** Timestamp of current frame in milliseconds (from performance.now()) */
|
|
1609
|
-
time:
|
|
1639
|
+
time: field21.float64().default(0),
|
|
1610
1640
|
/** Timestamp of previous frame in milliseconds (0 if first frame) */
|
|
1611
|
-
lastTime:
|
|
1641
|
+
lastTime: field21.float64().default(0)
|
|
1612
1642
|
}
|
|
1613
1643
|
);
|
|
1614
1644
|
|
|
1615
1645
|
// src/singletons/Grid.ts
|
|
1616
1646
|
import { CanvasSingletonDef as CanvasSingletonDef5 } from "@woven-ecs/canvas-store";
|
|
1617
|
-
import { field as
|
|
1647
|
+
import { field as field22 } from "@woven-ecs/core";
|
|
1618
1648
|
var GridSchema = {
|
|
1619
1649
|
/** Whether grid snapping is enabled */
|
|
1620
|
-
enabled:
|
|
1650
|
+
enabled: field22.boolean().default(false),
|
|
1621
1651
|
/** Whether resized/rotated objects must stay aligned to the grid */
|
|
1622
|
-
strict:
|
|
1652
|
+
strict: field22.boolean().default(false),
|
|
1623
1653
|
/** Width of each grid column in world units */
|
|
1624
|
-
colWidth:
|
|
1654
|
+
colWidth: field22.float64().default(20),
|
|
1625
1655
|
/** Height of each grid row in world units */
|
|
1626
|
-
rowHeight:
|
|
1656
|
+
rowHeight: field22.float64().default(20),
|
|
1627
1657
|
/** Angular snap increment in radians when grid is enabled */
|
|
1628
|
-
snapAngleRad:
|
|
1658
|
+
snapAngleRad: field22.float64().default(Math.PI / 36),
|
|
1629
1659
|
/** Angular snap increment in radians when shift key is held */
|
|
1630
|
-
shiftSnapAngleRad:
|
|
1660
|
+
shiftSnapAngleRad: field22.float64().default(Math.PI / 12)
|
|
1631
1661
|
};
|
|
1632
1662
|
var GridDef = class extends CanvasSingletonDef5 {
|
|
1633
1663
|
constructor() {
|
|
@@ -1690,14 +1720,14 @@ var Grid = new GridDef();
|
|
|
1690
1720
|
|
|
1691
1721
|
// src/singletons/Intersect.ts
|
|
1692
1722
|
import { CanvasSingletonDef as CanvasSingletonDef6 } from "@woven-ecs/canvas-store";
|
|
1693
|
-
import { field as
|
|
1723
|
+
import { field as field23 } from "@woven-ecs/core";
|
|
1694
1724
|
var IntersectSchema = {
|
|
1695
1725
|
// Store up to 5 intersected entity IDs
|
|
1696
|
-
entity1:
|
|
1697
|
-
entity2:
|
|
1698
|
-
entity3:
|
|
1699
|
-
entity4:
|
|
1700
|
-
entity5:
|
|
1726
|
+
entity1: field23.ref(),
|
|
1727
|
+
entity2: field23.ref(),
|
|
1728
|
+
entity3: field23.ref(),
|
|
1729
|
+
entity4: field23.ref(),
|
|
1730
|
+
entity5: field23.ref()
|
|
1701
1731
|
};
|
|
1702
1732
|
var IntersectDef = class extends CanvasSingletonDef6 {
|
|
1703
1733
|
constructor() {
|
|
@@ -1749,30 +1779,30 @@ var Intersect = new IntersectDef();
|
|
|
1749
1779
|
|
|
1750
1780
|
// src/singletons/Keyboard.ts
|
|
1751
1781
|
import { CanvasSingletonDef as CanvasSingletonDef7 } from "@woven-ecs/canvas-store";
|
|
1752
|
-
import { field as
|
|
1782
|
+
import { field as field24 } from "@woven-ecs/core";
|
|
1753
1783
|
var KEY_BUFFER_SIZE = 32;
|
|
1754
1784
|
var KeyboardSchema = {
|
|
1755
1785
|
/**
|
|
1756
1786
|
* Buffer where each bit represents whether a key is currently pressed.
|
|
1757
1787
|
* Uses field.buffer for zero-allocation subarray views.
|
|
1758
1788
|
*/
|
|
1759
|
-
keysDown:
|
|
1789
|
+
keysDown: field24.buffer(field24.uint8()).size(KEY_BUFFER_SIZE),
|
|
1760
1790
|
/**
|
|
1761
1791
|
* Buffer for key-down triggers (true for exactly 1 frame when key is pressed).
|
|
1762
1792
|
* Uses field.buffer for zero-allocation subarray views.
|
|
1763
1793
|
*/
|
|
1764
|
-
keysDownTrigger:
|
|
1794
|
+
keysDownTrigger: field24.buffer(field24.uint8()).size(KEY_BUFFER_SIZE),
|
|
1765
1795
|
/**
|
|
1766
1796
|
* Buffer for key-up triggers (true for exactly 1 frame when key is released).
|
|
1767
1797
|
* Uses field.buffer for zero-allocation subarray views.
|
|
1768
1798
|
*/
|
|
1769
|
-
keysUpTrigger:
|
|
1799
|
+
keysUpTrigger: field24.buffer(field24.uint8()).size(KEY_BUFFER_SIZE),
|
|
1770
1800
|
/** Common modifier - Shift key is down */
|
|
1771
|
-
shiftDown:
|
|
1801
|
+
shiftDown: field24.boolean().default(false),
|
|
1772
1802
|
/** Common modifier - Alt/Option key is down */
|
|
1773
|
-
altDown:
|
|
1803
|
+
altDown: field24.boolean().default(false),
|
|
1774
1804
|
/** Common modifier - Ctrl (Windows/Linux) or Cmd (Mac) is down */
|
|
1775
|
-
modDown:
|
|
1805
|
+
modDown: field24.boolean().default(false)
|
|
1776
1806
|
};
|
|
1777
1807
|
function getBit(buffer, bitIndex) {
|
|
1778
1808
|
if (bitIndex < 0 || bitIndex >= buffer.length * 8) return false;
|
|
@@ -2055,22 +2085,24 @@ var Key = {
|
|
|
2055
2085
|
|
|
2056
2086
|
// src/singletons/Mouse.ts
|
|
2057
2087
|
import { CanvasSingletonDef as CanvasSingletonDef8 } from "@woven-ecs/canvas-store";
|
|
2058
|
-
import { field as
|
|
2088
|
+
import { field as field25 } from "@woven-ecs/core";
|
|
2059
2089
|
var MouseSchema = {
|
|
2060
2090
|
/** Current mouse position relative to the editor element [x, y] */
|
|
2061
|
-
position:
|
|
2091
|
+
position: field25.tuple(field25.float32(), 2).default([0, 0]),
|
|
2062
2092
|
/** Horizontal wheel delta (positive = scroll right) */
|
|
2063
|
-
wheelDeltaX:
|
|
2093
|
+
wheelDeltaX: field25.float32().default(0),
|
|
2064
2094
|
/** Vertical wheel delta (positive = scroll down), normalized across browsers */
|
|
2065
|
-
wheelDeltaY:
|
|
2095
|
+
wheelDeltaY: field25.float32().default(0),
|
|
2066
2096
|
/** True for 1 frame when mouse moves */
|
|
2067
|
-
moveTrigger:
|
|
2097
|
+
moveTrigger: field25.boolean().default(false),
|
|
2068
2098
|
/** True for 1 frame when wheel is scrolled */
|
|
2069
|
-
wheelTrigger:
|
|
2099
|
+
wheelTrigger: field25.boolean().default(false),
|
|
2070
2100
|
/** True for 1 frame when mouse enters the editor element */
|
|
2071
|
-
enterTrigger:
|
|
2101
|
+
enterTrigger: field25.boolean().default(false),
|
|
2072
2102
|
/** True for 1 frame when mouse leaves the editor element */
|
|
2073
|
-
leaveTrigger:
|
|
2103
|
+
leaveTrigger: field25.boolean().default(false),
|
|
2104
|
+
/** Whether the mouse is over a UI element (not the canvas) */
|
|
2105
|
+
obscured: field25.boolean().default(false)
|
|
2074
2106
|
};
|
|
2075
2107
|
var MouseDef = class extends CanvasSingletonDef8 {
|
|
2076
2108
|
constructor() {
|
|
@@ -2102,16 +2134,20 @@ var MouseDef = class extends CanvasSingletonDef8 {
|
|
|
2102
2134
|
const m = this.read(ctx);
|
|
2103
2135
|
return [m.wheelDeltaX, m.wheelDeltaY];
|
|
2104
2136
|
}
|
|
2137
|
+
/** Check if mouse is over a UI element (not the canvas) */
|
|
2138
|
+
isObscured(ctx) {
|
|
2139
|
+
return this.read(ctx).obscured;
|
|
2140
|
+
}
|
|
2105
2141
|
};
|
|
2106
2142
|
var Mouse = new MouseDef();
|
|
2107
2143
|
|
|
2108
2144
|
// src/singletons/RankBounds.ts
|
|
2109
2145
|
import { CanvasSingletonDef as CanvasSingletonDef9 } from "@woven-ecs/canvas-store";
|
|
2110
|
-
import { field as
|
|
2146
|
+
import { field as field26 } from "@woven-ecs/core";
|
|
2111
2147
|
import { generateJitteredKeyBetween } from "fractional-indexing-jittered";
|
|
2112
2148
|
var RankBoundsSchema = {
|
|
2113
|
-
minRank:
|
|
2114
|
-
maxRank:
|
|
2149
|
+
minRank: field26.string().max(36).default(""),
|
|
2150
|
+
maxRank: field26.string().max(36).default("")
|
|
2115
2151
|
};
|
|
2116
2152
|
var RankBoundsDef = class extends CanvasSingletonDef9 {
|
|
2117
2153
|
constructor() {
|
|
@@ -2170,12 +2206,12 @@ var RankBounds = new RankBoundsDef();
|
|
|
2170
2206
|
|
|
2171
2207
|
// src/singletons/ScaleWithZoomState.ts
|
|
2172
2208
|
import { defineCanvasSingleton as defineCanvasSingleton2 } from "@woven-ecs/canvas-store";
|
|
2173
|
-
import { field as
|
|
2209
|
+
import { field as field27 } from "@woven-ecs/core";
|
|
2174
2210
|
var ScaleWithZoomState = defineCanvasSingleton2(
|
|
2175
2211
|
{ name: "scaleWithZoomState" },
|
|
2176
2212
|
{
|
|
2177
2213
|
/** Last processed zoom level */
|
|
2178
|
-
lastZoom:
|
|
2214
|
+
lastZoom: field27.float64().default(1)
|
|
2179
2215
|
}
|
|
2180
2216
|
);
|
|
2181
2217
|
|
|
@@ -2188,12 +2224,12 @@ import {
|
|
|
2188
2224
|
createEntity,
|
|
2189
2225
|
defineComponent,
|
|
2190
2226
|
defineQuery,
|
|
2191
|
-
field as
|
|
2227
|
+
field as field28,
|
|
2192
2228
|
getResources,
|
|
2193
2229
|
removeEntity
|
|
2194
2230
|
} from "@woven-ecs/core";
|
|
2195
2231
|
var CommandMarker = defineComponent({
|
|
2196
|
-
name:
|
|
2232
|
+
name: field28.string().max(128)
|
|
2197
2233
|
});
|
|
2198
2234
|
var editorPayloads = /* @__PURE__ */ new WeakMap();
|
|
2199
2235
|
function getPayloadMap(ctx) {
|
|
@@ -2332,6 +2368,7 @@ function detachKeyboardListeners(domElement) {
|
|
|
2332
2368
|
}
|
|
2333
2369
|
var keyboardSystem = defineEditorSystem({ phase: "input" }, (ctx) => {
|
|
2334
2370
|
const resources = getResources3(ctx);
|
|
2371
|
+
if (!resources.domElement) return;
|
|
2335
2372
|
const state = instanceState.get(resources.domElement);
|
|
2336
2373
|
if (!state) return;
|
|
2337
2374
|
on(ctx, ResetKeyboard, () => {
|
|
@@ -2394,7 +2431,8 @@ function attachMouseListeners(domElement) {
|
|
|
2394
2431
|
state.eventsBuffer.push({
|
|
2395
2432
|
type: "mousemove",
|
|
2396
2433
|
clientX: e.clientX,
|
|
2397
|
-
clientY: e.clientY
|
|
2434
|
+
clientY: e.clientY,
|
|
2435
|
+
target: e.target
|
|
2398
2436
|
});
|
|
2399
2437
|
},
|
|
2400
2438
|
onWheel: (e) => {
|
|
@@ -2432,6 +2470,7 @@ function detachMouseListeners(domElement) {
|
|
|
2432
2470
|
}
|
|
2433
2471
|
var mouseSystem = defineEditorSystem({ phase: "input" }, (ctx) => {
|
|
2434
2472
|
const resources = getResources4(ctx);
|
|
2473
|
+
if (!resources.domElement) return;
|
|
2435
2474
|
const state = instanceState2.get(resources.domElement);
|
|
2436
2475
|
if (!state) return;
|
|
2437
2476
|
const currentMouse = Mouse.read(ctx);
|
|
@@ -2451,6 +2490,7 @@ var mouseSystem = defineEditorSystem({ phase: "input" }, (ctx) => {
|
|
|
2451
2490
|
case "mousemove":
|
|
2452
2491
|
mouse.position = [event.clientX - screen.left, event.clientY - screen.top];
|
|
2453
2492
|
mouse.moveTrigger = true;
|
|
2493
|
+
mouse.obscured = event.target !== resources.domElement;
|
|
2454
2494
|
break;
|
|
2455
2495
|
case "wheel":
|
|
2456
2496
|
mouse.wheelDeltaX = event.deltaX;
|
|
@@ -2579,6 +2619,7 @@ function detachPointerListeners(domElement) {
|
|
|
2579
2619
|
var pointerSystem = defineEditorSystem({ phase: "input" }, (ctx) => {
|
|
2580
2620
|
const resources = getResources5(ctx);
|
|
2581
2621
|
const { domElement } = resources;
|
|
2622
|
+
if (!domElement) return;
|
|
2582
2623
|
const state = instanceState3.get(domElement);
|
|
2583
2624
|
if (!state) return;
|
|
2584
2625
|
state.frameCount++;
|
|
@@ -2658,6 +2699,7 @@ function detachScreenObserver(domElement) {
|
|
|
2658
2699
|
var screenSystem = defineEditorSystem({ phase: "input" }, (ctx) => {
|
|
2659
2700
|
const resources = getResources6(ctx);
|
|
2660
2701
|
const { domElement } = resources;
|
|
2702
|
+
if (!domElement) return;
|
|
2661
2703
|
const state = instanceState4.get(domElement);
|
|
2662
2704
|
if (!state) return;
|
|
2663
2705
|
const frame = Frame.read(ctx);
|
|
@@ -2684,6 +2726,7 @@ function getCursorSvg(cursors, kind, rotateZ) {
|
|
|
2684
2726
|
return `url("data:image/svg+xml,${encodeURIComponent(svg.trim())}") ${def.hotspot[0]} ${def.hotspot[1]}, auto`;
|
|
2685
2727
|
}
|
|
2686
2728
|
var cursorSystem = defineEditorSystem({ phase: "render", priority: -100 }, (ctx) => {
|
|
2729
|
+
if (typeof document === "undefined") return;
|
|
2687
2730
|
const changedCursors = cursorQuery.changed(ctx);
|
|
2688
2731
|
const frame = Frame.read(ctx);
|
|
2689
2732
|
if (changedCursors.length === 0 && frame.number !== 1) {
|
|
@@ -2715,6 +2758,9 @@ function getBlockDef(ctx, tag) {
|
|
|
2715
2758
|
function canBlockEdit(ctx, tag) {
|
|
2716
2759
|
return getBlockDef(ctx, tag).editOptions.canEdit;
|
|
2717
2760
|
}
|
|
2761
|
+
function canBlockSelect(ctx, tag) {
|
|
2762
|
+
return getBlockDef(ctx, tag).selectable;
|
|
2763
|
+
}
|
|
2718
2764
|
function getBlockResizeMode(ctx, entityId) {
|
|
2719
2765
|
const block = Block.read(ctx, entityId);
|
|
2720
2766
|
if (block.resizeMode !== ResizeMode.Default) {
|
|
@@ -2737,6 +2783,136 @@ function computeAabb(ctx, entityId, out) {
|
|
|
2737
2783
|
}
|
|
2738
2784
|
}
|
|
2739
2785
|
|
|
2786
|
+
// src/helpers/embed.ts
|
|
2787
|
+
function detectEmbedProvider(url) {
|
|
2788
|
+
try {
|
|
2789
|
+
const parsed = new URL(url);
|
|
2790
|
+
const host = parsed.hostname.replace(/^www\./, "");
|
|
2791
|
+
if (host === "youtube.com" || host === "youtu.be") return "youtube" /* Youtube */;
|
|
2792
|
+
if (host === "open.spotify.com" || host === "spotify.com") return "spotify" /* Spotify */;
|
|
2793
|
+
if (host === "google.com" && parsed.pathname.startsWith("/maps")) return "google-maps" /* GoogleMaps */;
|
|
2794
|
+
if (host === "maps.google.com") return "google-maps" /* GoogleMaps */;
|
|
2795
|
+
if (host === "calendar.google.com") return "google-calendar" /* GoogleCalendar */;
|
|
2796
|
+
if (host === "docs.google.com" && parsed.pathname.includes("/presentation")) return "google-slides" /* GoogleSlides */;
|
|
2797
|
+
if (host === "figma.com" || host.endsWith(".figma.com")) return "figma" /* Figma */;
|
|
2798
|
+
if (host === "gist.github.com") return "github-gist" /* GithubGist */;
|
|
2799
|
+
if (host === "tldraw.com" || host.endsWith(".tldraw.com")) return "tldraw" /* Tldraw */;
|
|
2800
|
+
return "unknown" /* Unknown */;
|
|
2801
|
+
} catch {
|
|
2802
|
+
return "unknown" /* Unknown */;
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
function validateEmbedUrl(url, provider) {
|
|
2806
|
+
try {
|
|
2807
|
+
const parsed = new URL(url);
|
|
2808
|
+
const host = parsed.hostname.replace(/^www\./, "");
|
|
2809
|
+
switch (provider) {
|
|
2810
|
+
case "youtube" /* Youtube */: {
|
|
2811
|
+
if (host === "youtu.be") return null;
|
|
2812
|
+
if (host !== "youtube.com") return "URL must be from youtube.com";
|
|
2813
|
+
if (parsed.pathname === "/watch" && parsed.searchParams.has("v")) return null;
|
|
2814
|
+
if (parsed.pathname.startsWith("/embed/")) return null;
|
|
2815
|
+
return "Paste a YouTube video link (e.g. youtube.com/watch?v=...)";
|
|
2816
|
+
}
|
|
2817
|
+
case "spotify" /* Spotify */: {
|
|
2818
|
+
if (host !== "open.spotify.com" && host !== "spotify.com") return "URL must be from open.spotify.com";
|
|
2819
|
+
if (parsed.pathname.length <= 1) return "Paste a Spotify track, album, or playlist link";
|
|
2820
|
+
return null;
|
|
2821
|
+
}
|
|
2822
|
+
case "google-maps" /* GoogleMaps */: {
|
|
2823
|
+
if (host !== "google.com" && host !== "maps.google.com") return "URL must be from google.com/maps";
|
|
2824
|
+
if (!parsed.pathname.startsWith("/maps") && host !== "maps.google.com") return "Paste a Google Maps link";
|
|
2825
|
+
return null;
|
|
2826
|
+
}
|
|
2827
|
+
case "google-calendar" /* GoogleCalendar */: {
|
|
2828
|
+
if (host !== "calendar.google.com") return "URL must be from calendar.google.com";
|
|
2829
|
+
return null;
|
|
2830
|
+
}
|
|
2831
|
+
case "google-slides" /* GoogleSlides */: {
|
|
2832
|
+
if (host !== "docs.google.com") return "URL must be from docs.google.com";
|
|
2833
|
+
if (!parsed.pathname.includes("/presentation/")) return "Paste a Google Slides presentation link";
|
|
2834
|
+
return null;
|
|
2835
|
+
}
|
|
2836
|
+
case "figma" /* Figma */: {
|
|
2837
|
+
if (host !== "figma.com" && !host.endsWith(".figma.com")) return "URL must be from figma.com";
|
|
2838
|
+
return null;
|
|
2839
|
+
}
|
|
2840
|
+
case "github-gist" /* GithubGist */: {
|
|
2841
|
+
if (host !== "gist.github.com") return "URL must be from gist.github.com";
|
|
2842
|
+
return null;
|
|
2843
|
+
}
|
|
2844
|
+
case "tldraw" /* Tldraw */: {
|
|
2845
|
+
if (host !== "tldraw.com" && !host.endsWith(".tldraw.com")) return "URL must be from tldraw.com";
|
|
2846
|
+
return null;
|
|
2847
|
+
}
|
|
2848
|
+
default:
|
|
2849
|
+
return null;
|
|
2850
|
+
}
|
|
2851
|
+
} catch {
|
|
2852
|
+
return "Please enter a valid URL";
|
|
2853
|
+
}
|
|
2854
|
+
}
|
|
2855
|
+
function resolveEmbedUrl(url, provider) {
|
|
2856
|
+
const p = provider ?? detectEmbedProvider(url);
|
|
2857
|
+
try {
|
|
2858
|
+
const parsed = new URL(url);
|
|
2859
|
+
switch (p) {
|
|
2860
|
+
case "youtube" /* Youtube */: {
|
|
2861
|
+
const host = parsed.hostname.replace(/^www\./, "");
|
|
2862
|
+
if (host === "youtu.be") {
|
|
2863
|
+
const videoId2 = parsed.pathname.slice(1);
|
|
2864
|
+
return `https://www.youtube.com/embed/${videoId2}`;
|
|
2865
|
+
}
|
|
2866
|
+
const videoId = parsed.searchParams.get("v");
|
|
2867
|
+
if (videoId && parsed.pathname === "/watch") {
|
|
2868
|
+
return `https://www.youtube.com/embed/${videoId}`;
|
|
2869
|
+
}
|
|
2870
|
+
return url;
|
|
2871
|
+
}
|
|
2872
|
+
case "spotify" /* Spotify */: {
|
|
2873
|
+
if (!parsed.pathname.startsWith("/embed/")) {
|
|
2874
|
+
return `https://open.spotify.com/embed${parsed.pathname}`;
|
|
2875
|
+
}
|
|
2876
|
+
return url;
|
|
2877
|
+
}
|
|
2878
|
+
case "google-maps" /* GoogleMaps */: {
|
|
2879
|
+
if (parsed.pathname.startsWith("/maps/embed")) return url;
|
|
2880
|
+
if (parsed.searchParams.get("output") === "embed") return url;
|
|
2881
|
+
const placeMatch = parsed.pathname.match(/\/maps\/place\/([^/]+)/);
|
|
2882
|
+
if (placeMatch) {
|
|
2883
|
+
return `https://www.google.com/maps?q=${encodeURIComponent(decodeURIComponent(placeMatch[1]))}&output=embed`;
|
|
2884
|
+
}
|
|
2885
|
+
const q = parsed.searchParams.get("q");
|
|
2886
|
+
if (q) {
|
|
2887
|
+
return `https://www.google.com/maps?q=${encodeURIComponent(q)}&output=embed`;
|
|
2888
|
+
}
|
|
2889
|
+
const atMatch = parsed.pathname.match(/\/@(-?[\d.]+),(-?[\d.]+),(\d+\.?\d*)z/);
|
|
2890
|
+
if (atMatch) {
|
|
2891
|
+
const [, lat, lng, zoom] = atMatch;
|
|
2892
|
+
return `https://www.google.com/maps?q=${lat},${lng}&z=${Math.round(parseFloat(zoom))}&output=embed`;
|
|
2893
|
+
}
|
|
2894
|
+
return `https://www.google.com/maps?q=${encodeURIComponent(url)}&output=embed`;
|
|
2895
|
+
}
|
|
2896
|
+
case "google-slides" /* GoogleSlides */: {
|
|
2897
|
+
return url.replace(/\/(edit|pub)(#.*)?(\?.*)?$/, "/embed");
|
|
2898
|
+
}
|
|
2899
|
+
case "figma" /* Figma */: {
|
|
2900
|
+
return `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(url)}`;
|
|
2901
|
+
}
|
|
2902
|
+
case "github-gist" /* GithubGist */: {
|
|
2903
|
+
if (!url.endsWith(".pibb")) {
|
|
2904
|
+
return `${url}.pibb`;
|
|
2905
|
+
}
|
|
2906
|
+
return url;
|
|
2907
|
+
}
|
|
2908
|
+
default:
|
|
2909
|
+
return url;
|
|
2910
|
+
}
|
|
2911
|
+
} catch {
|
|
2912
|
+
return url;
|
|
2913
|
+
}
|
|
2914
|
+
}
|
|
2915
|
+
|
|
2740
2916
|
// src/helpers/held.ts
|
|
2741
2917
|
import { getResources as getResources9, hasComponent as hasComponent2 } from "@woven-ecs/core";
|
|
2742
2918
|
function isHeldByRemote(ctx, entityId) {
|
|
@@ -2923,7 +3099,7 @@ function updateUserPosition(ctx, position) {
|
|
|
2923
3099
|
}
|
|
2924
3100
|
|
|
2925
3101
|
// src/systems/preCapture/intersectSystem.ts
|
|
2926
|
-
import { addComponent as addComponent4, defineQuery as defineQuery6, hasComponent as hasComponent5, removeComponent } from "@woven-ecs/core";
|
|
3102
|
+
import { addComponent as addComponent4, defineQuery as defineQuery6, getResources as getResources11, hasComponent as hasComponent5, removeComponent } from "@woven-ecs/core";
|
|
2927
3103
|
var blocksChanged = defineQuery6((q) => q.tracking(Block));
|
|
2928
3104
|
var hitGeometryChanged = defineQuery6((q) => q.tracking(HitGeometry));
|
|
2929
3105
|
var heldQuery = defineQuery6((q) => q.with(Held).tracking(Held));
|
|
@@ -2962,6 +3138,7 @@ function arraysEqual(a, b) {
|
|
|
2962
3138
|
}
|
|
2963
3139
|
var added = /* @__PURE__ */ new Set();
|
|
2964
3140
|
var changed = /* @__PURE__ */ new Set();
|
|
3141
|
+
var prevObscuredByElement = /* @__PURE__ */ new WeakMap();
|
|
2965
3142
|
var intersectSystem = defineEditorSystem({ phase: "capture", priority: 100 }, (ctx) => {
|
|
2966
3143
|
added.clear();
|
|
2967
3144
|
for (const entityId of blocksChanged.added(ctx)) {
|
|
@@ -3003,6 +3180,17 @@ var intersectSystem = defineEditorSystem({ phase: "capture", priority: 100 }, (c
|
|
|
3003
3180
|
clearHovered(ctx);
|
|
3004
3181
|
return;
|
|
3005
3182
|
}
|
|
3183
|
+
const resources = getResources11(ctx);
|
|
3184
|
+
const isObscured = Mouse.isObscured(ctx);
|
|
3185
|
+
const wasObscured = resources.domElement ? prevObscuredByElement.get(resources.domElement) ?? false : false;
|
|
3186
|
+
const obscuredChanged = isObscured !== wasObscured;
|
|
3187
|
+
if (resources.domElement) {
|
|
3188
|
+
prevObscuredByElement.set(resources.domElement, isObscured);
|
|
3189
|
+
}
|
|
3190
|
+
if (isObscured) {
|
|
3191
|
+
clearHovered(ctx);
|
|
3192
|
+
return;
|
|
3193
|
+
}
|
|
3006
3194
|
const mousePos = Mouse.getPosition(ctx);
|
|
3007
3195
|
const worldPos = Camera.toWorld(ctx, mousePos);
|
|
3008
3196
|
const intersected = intersectPoint(ctx, worldPos);
|
|
@@ -3015,7 +3203,7 @@ var intersectSystem = defineEditorSystem({ phase: "capture", priority: 100 }, (c
|
|
|
3015
3203
|
if (pointers.length > 0) {
|
|
3016
3204
|
return;
|
|
3017
3205
|
}
|
|
3018
|
-
if (intersectsChanged || heldChanged) {
|
|
3206
|
+
if (intersectsChanged || heldChanged || obscuredChanged) {
|
|
3019
3207
|
updateHovered(ctx, intersected);
|
|
3020
3208
|
}
|
|
3021
3209
|
});
|
|
@@ -3117,7 +3305,7 @@ function scaleBlock(ctx, entityId, zoom) {
|
|
|
3117
3305
|
|
|
3118
3306
|
// src/CorePlugin.ts
|
|
3119
3307
|
var CorePlugin = {
|
|
3120
|
-
name:
|
|
3308
|
+
name: CORE_PLUGIN_NAME,
|
|
3121
3309
|
singletons: Object.values(singletons_exports).filter((v) => v instanceof CanvasSingletonDef10),
|
|
3122
3310
|
components: Object.values(components_exports).filter((v) => v instanceof CanvasComponentDef6),
|
|
3123
3311
|
blockDefs: [
|
|
@@ -3149,6 +3337,14 @@ var CorePlugin = {
|
|
|
3149
3337
|
editOptions: {
|
|
3150
3338
|
canEdit: true
|
|
3151
3339
|
}
|
|
3340
|
+
},
|
|
3341
|
+
{
|
|
3342
|
+
tag: "embed",
|
|
3343
|
+
components: [Embed],
|
|
3344
|
+
resizeMode: ResizeMode.Free,
|
|
3345
|
+
editOptions: {
|
|
3346
|
+
canEdit: true
|
|
3347
|
+
}
|
|
3152
3348
|
}
|
|
3153
3349
|
],
|
|
3154
3350
|
systems: [
|
|
@@ -3176,14 +3372,16 @@ var CorePlugin = {
|
|
|
3176
3372
|
// priority: -100
|
|
3177
3373
|
],
|
|
3178
3374
|
setup(ctx) {
|
|
3179
|
-
const { domElement } =
|
|
3375
|
+
const { domElement } = getResources12(ctx);
|
|
3376
|
+
if (!domElement) return;
|
|
3180
3377
|
attachKeyboardListeners(domElement);
|
|
3181
3378
|
attachMouseListeners(domElement);
|
|
3182
3379
|
attachScreenObserver(domElement);
|
|
3183
3380
|
attachPointerListeners(domElement);
|
|
3184
3381
|
},
|
|
3185
3382
|
teardown(ctx) {
|
|
3186
|
-
const { domElement } =
|
|
3383
|
+
const { domElement } = getResources12(ctx);
|
|
3384
|
+
if (!domElement) return;
|
|
3187
3385
|
detachKeyboardListeners(domElement);
|
|
3188
3386
|
detachMouseListeners(domElement);
|
|
3189
3387
|
detachScreenObserver(domElement);
|
|
@@ -3284,6 +3482,9 @@ var FontLoader = class {
|
|
|
3284
3482
|
*/
|
|
3285
3483
|
loadSingleFont(family) {
|
|
3286
3484
|
this.loadedFonts.add(family.name);
|
|
3485
|
+
if (typeof document === "undefined") {
|
|
3486
|
+
return Promise.resolve();
|
|
3487
|
+
}
|
|
3287
3488
|
return new Promise((resolve, reject) => {
|
|
3288
3489
|
const link = document.createElement("link");
|
|
3289
3490
|
link.rel = "stylesheet";
|
|
@@ -3662,11 +3863,54 @@ var Editor = class {
|
|
|
3662
3863
|
_getContext() {
|
|
3663
3864
|
return this.ctx;
|
|
3664
3865
|
}
|
|
3866
|
+
/**
|
|
3867
|
+
* Attach a DOM element to a headless editor.
|
|
3868
|
+
* Use this after SSR to connect input listeners and enable rendering.
|
|
3869
|
+
*
|
|
3870
|
+
* @param domElement - The DOM element to attach to
|
|
3871
|
+
*
|
|
3872
|
+
* @example
|
|
3873
|
+
* ```typescript
|
|
3874
|
+
* // SSR: create headless editor
|
|
3875
|
+
* const editor = new Editor(null, { plugins: [...] });
|
|
3876
|
+
* await editor.initialize();
|
|
3877
|
+
* editor.tick(); // process initial state
|
|
3878
|
+
*
|
|
3879
|
+
* // Client hydration: attach the DOM
|
|
3880
|
+
* editor.attachDom(document.getElementById('canvas')!);
|
|
3881
|
+
* ```
|
|
3882
|
+
*/
|
|
3883
|
+
attachDom(domElement) {
|
|
3884
|
+
const resources = this.ctx.resources;
|
|
3885
|
+
if (resources.domElement) {
|
|
3886
|
+
throw new Error("Editor already has a DOM element attached. Call detachDom() first.");
|
|
3887
|
+
}
|
|
3888
|
+
resources.domElement = domElement;
|
|
3889
|
+
attachKeyboardListeners(domElement);
|
|
3890
|
+
attachMouseListeners(domElement);
|
|
3891
|
+
attachScreenObserver(domElement);
|
|
3892
|
+
attachPointerListeners(domElement);
|
|
3893
|
+
}
|
|
3894
|
+
/**
|
|
3895
|
+
* Detach the current DOM element.
|
|
3896
|
+
* Removes all input listeners. The editor continues to run headless.
|
|
3897
|
+
*/
|
|
3898
|
+
detachDom() {
|
|
3899
|
+
const resources = this.ctx.resources;
|
|
3900
|
+
const { domElement } = resources;
|
|
3901
|
+
if (!domElement) return;
|
|
3902
|
+
detachKeyboardListeners(domElement);
|
|
3903
|
+
detachMouseListeners(domElement);
|
|
3904
|
+
detachScreenObserver(domElement);
|
|
3905
|
+
detachPointerListeners(domElement);
|
|
3906
|
+
resources.domElement = null;
|
|
3907
|
+
}
|
|
3665
3908
|
/**
|
|
3666
3909
|
* Clean up the editor.
|
|
3667
3910
|
* Call this when done to release resources.
|
|
3668
3911
|
*/
|
|
3669
3912
|
dispose() {
|
|
3913
|
+
this.detachDom();
|
|
3670
3914
|
const plugins = Array.from(this.plugins.values()).reverse();
|
|
3671
3915
|
for (const plugin of plugins) {
|
|
3672
3916
|
if (plugin.teardown) {
|
|
@@ -3983,6 +4227,8 @@ export {
|
|
|
3983
4227
|
Edited,
|
|
3984
4228
|
Editor,
|
|
3985
4229
|
EditorStateDef,
|
|
4230
|
+
Embed,
|
|
4231
|
+
EmbedProvider,
|
|
3986
4232
|
EventType,
|
|
3987
4233
|
FontFamily,
|
|
3988
4234
|
FontLoader,
|
|
@@ -4028,16 +4274,18 @@ export {
|
|
|
4028
4274
|
VerticalAlignment,
|
|
4029
4275
|
addComponent6 as addComponent,
|
|
4030
4276
|
canBlockEdit,
|
|
4277
|
+
canBlockSelect,
|
|
4031
4278
|
clearPointerTrackingState,
|
|
4032
4279
|
createEntity5 as createEntity,
|
|
4033
|
-
|
|
4280
|
+
defineCanvasComponent14 as defineCanvasComponent,
|
|
4034
4281
|
defineCanvasSingleton3 as defineCanvasSingleton,
|
|
4035
4282
|
defineCommand,
|
|
4036
4283
|
defineEditorState,
|
|
4037
4284
|
defineEditorSystem,
|
|
4038
4285
|
defineQuery11 as defineQuery,
|
|
4039
4286
|
defineSystem,
|
|
4040
|
-
|
|
4287
|
+
detectEmbedProvider,
|
|
4288
|
+
field29 as field,
|
|
4041
4289
|
getBackrefs,
|
|
4042
4290
|
getBlockDef,
|
|
4043
4291
|
getBlockResizeMode,
|
|
@@ -4046,7 +4294,7 @@ export {
|
|
|
4046
4294
|
getMouseInput,
|
|
4047
4295
|
getPluginResources,
|
|
4048
4296
|
getPointerInput,
|
|
4049
|
-
|
|
4297
|
+
getResources13 as getResources,
|
|
4050
4298
|
getTopmostBlockAtPoint,
|
|
4051
4299
|
hasComponent7 as hasComponent,
|
|
4052
4300
|
intersectAabb,
|
|
@@ -4058,6 +4306,8 @@ export {
|
|
|
4058
4306
|
parsePlugin,
|
|
4059
4307
|
removeComponent2 as removeComponent,
|
|
4060
4308
|
removeEntity3 as removeEntity,
|
|
4061
|
-
|
|
4309
|
+
resolveEmbedUrl,
|
|
4310
|
+
runMachine,
|
|
4311
|
+
validateEmbedUrl
|
|
4062
4312
|
};
|
|
4063
4313
|
//# sourceMappingURL=index.js.map
|