@llc3233149/core 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canvaskit.d.ts +9 -0
- package/dist/canvaskit.d.ts.map +1 -0
- package/dist/canvaskit.js +55 -0
- package/dist/canvaskit.js.map +1 -0
- package/dist/clipboard.d.ts +32 -0
- package/dist/clipboard.d.ts.map +1 -0
- package/dist/clipboard.js +345 -0
- package/dist/clipboard.js.map +1 -0
- package/dist/color.d.ts +28 -0
- package/dist/color.d.ts.map +1 -0
- package/dist/color.js +67 -0
- package/dist/color.js.map +1 -0
- package/dist/constants.d.ts +159 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +224 -0
- package/dist/constants.js.map +1 -0
- package/dist/copy.d.ts +20 -0
- package/dist/copy.d.ts.map +1 -0
- package/dist/copy.js +64 -0
- package/dist/copy.js.map +1 -0
- package/dist/fig-export-worker.d.ts +2 -0
- package/dist/fig-export-worker.d.ts.map +1 -0
- package/dist/fig-export-worker.js +17 -0
- package/dist/fig-export-worker.js.map +1 -0
- package/dist/fig-export.d.ts +13 -0
- package/dist/fig-export.d.ts.map +1 -0
- package/dist/fig-export.js +243 -0
- package/dist/fig-export.js.map +1 -0
- package/dist/figma-api.d.ts +268 -0
- package/dist/figma-api.d.ts.map +1 -0
- package/dist/figma-api.js +1074 -0
- package/dist/figma-api.js.map +1 -0
- package/dist/figma-rest-import.d.ts +122 -0
- package/dist/figma-rest-import.d.ts.map +1 -0
- package/dist/figma-rest-import.js +319 -0
- package/dist/figma-rest-import.js.map +1 -0
- package/dist/fonts.d.ts +24 -0
- package/dist/fonts.d.ts.map +1 -0
- package/dist/fonts.js +356 -0
- package/dist/fonts.js.map +1 -0
- package/dist/geometry.d.ts +14 -0
- package/dist/geometry.d.ts.map +1 -0
- package/dist/geometry.js +47 -0
- package/dist/geometry.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/kiwi/codec.d.ts +292 -0
- package/dist/kiwi/codec.d.ts.map +1 -0
- package/dist/kiwi/codec.js +340 -0
- package/dist/kiwi/codec.js.map +1 -0
- package/dist/kiwi/fig-file.d.ts +4 -0
- package/dist/kiwi/fig-file.d.ts.map +1 -0
- package/dist/kiwi/fig-file.js +236 -0
- package/dist/kiwi/fig-file.js.map +1 -0
- package/dist/kiwi/fig-import.d.ts +4 -0
- package/dist/kiwi/fig-import.d.ts.map +1 -0
- package/dist/kiwi/fig-import.js +248 -0
- package/dist/kiwi/fig-import.js.map +1 -0
- package/dist/kiwi/fig-parse-worker.d.ts +7 -0
- package/dist/kiwi/fig-parse-worker.d.ts.map +1 -0
- package/dist/kiwi/fig-parse-worker.js +184 -0
- package/dist/kiwi/fig-parse-worker.js.map +1 -0
- package/dist/kiwi/instance-overrides.d.ts +66 -0
- package/dist/kiwi/instance-overrides.d.ts.map +1 -0
- package/dist/kiwi/instance-overrides.js +644 -0
- package/dist/kiwi/instance-overrides.js.map +1 -0
- package/dist/kiwi/kiwi-convert.d.ts +19 -0
- package/dist/kiwi/kiwi-convert.d.ts.map +1 -0
- package/dist/kiwi/kiwi-convert.js +678 -0
- package/dist/kiwi/kiwi-convert.js.map +1 -0
- package/dist/kiwi/kiwi-schema/bb.d.ts +25 -0
- package/dist/kiwi/kiwi-schema/bb.d.ts.map +1 -0
- package/dist/kiwi/kiwi-schema/bb.js +225 -0
- package/dist/kiwi/kiwi-schema/bb.js.map +1 -0
- package/dist/kiwi/kiwi-schema/binary.d.ts +5 -0
- package/dist/kiwi/kiwi-schema/binary.d.ts.map +1 -0
- package/dist/kiwi/kiwi-schema/binary.js +86 -0
- package/dist/kiwi/kiwi-schema/binary.js.map +1 -0
- package/dist/kiwi/kiwi-schema/index.d.ts +6 -0
- package/dist/kiwi/kiwi-schema/index.d.ts.map +1 -0
- package/dist/kiwi/kiwi-schema/index.js +5 -0
- package/dist/kiwi/kiwi-schema/index.js.map +1 -0
- package/dist/kiwi/kiwi-schema/js.d.ts +4 -0
- package/dist/kiwi/kiwi-schema/js.d.ts.map +1 -0
- package/dist/kiwi/kiwi-schema/js.js +282 -0
- package/dist/kiwi/kiwi-schema/js.js.map +1 -0
- package/dist/kiwi/kiwi-schema/parser.d.ts +5 -0
- package/dist/kiwi/kiwi-schema/parser.d.ts.map +1 -0
- package/dist/kiwi/kiwi-schema/parser.js +228 -0
- package/dist/kiwi/kiwi-schema/parser.js.map +1 -0
- package/dist/kiwi/kiwi-schema/schema.d.ts +22 -0
- package/dist/kiwi/kiwi-schema/schema.d.ts.map +1 -0
- package/dist/kiwi/kiwi-schema/schema.js +2 -0
- package/dist/kiwi/kiwi-schema/schema.js.map +1 -0
- package/dist/kiwi/kiwi-schema/util.d.ts +3 -0
- package/dist/kiwi/kiwi-schema/util.d.ts.map +1 -0
- package/dist/kiwi/kiwi-schema/util.js +10 -0
- package/dist/kiwi/kiwi-schema/util.js.map +1 -0
- package/dist/kiwi/protocol.d.ts +172 -0
- package/dist/kiwi/protocol.d.ts.map +1 -0
- package/dist/kiwi/protocol.js +214 -0
- package/dist/kiwi/protocol.js.map +1 -0
- package/dist/kiwi/schema.d.ts +3 -0
- package/dist/kiwi/schema.d.ts.map +1 -0
- package/dist/kiwi/schema.js +2285 -0
- package/dist/kiwi/schema.js.map +1 -0
- package/dist/kiwi-serialize.d.ts +17 -0
- package/dist/kiwi-serialize.d.ts.map +1 -0
- package/dist/kiwi-serialize.js +419 -0
- package/dist/kiwi-serialize.js.map +1 -0
- package/dist/layout.d.ts +9 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +533 -0
- package/dist/layout.js.map +1 -0
- package/dist/profiler/draw-call-counter.d.ts +9 -0
- package/dist/profiler/draw-call-counter.d.ts.map +1 -0
- package/dist/profiler/draw-call-counter.js +37 -0
- package/dist/profiler/draw-call-counter.js.map +1 -0
- package/dist/profiler/frame-capture.d.ts +34 -0
- package/dist/profiler/frame-capture.d.ts.map +1 -0
- package/dist/profiler/frame-capture.js +90 -0
- package/dist/profiler/frame-capture.js.map +1 -0
- package/dist/profiler/frame-stats.d.ts +33 -0
- package/dist/profiler/frame-stats.d.ts.map +1 -0
- package/dist/profiler/frame-stats.js +103 -0
- package/dist/profiler/frame-stats.js.map +1 -0
- package/dist/profiler/gpu-timer.d.ts +15 -0
- package/dist/profiler/gpu-timer.d.ts.map +1 -0
- package/dist/profiler/gpu-timer.js +77 -0
- package/dist/profiler/gpu-timer.js.map +1 -0
- package/dist/profiler/hud-renderer.d.ts +22 -0
- package/dist/profiler/hud-renderer.d.ts.map +1 -0
- package/dist/profiler/hud-renderer.js +200 -0
- package/dist/profiler/hud-renderer.js.map +1 -0
- package/dist/profiler/index.d.ts +9 -0
- package/dist/profiler/index.d.ts.map +1 -0
- package/dist/profiler/index.js +8 -0
- package/dist/profiler/index.js.map +1 -0
- package/dist/profiler/phase-timer.d.ts +9 -0
- package/dist/profiler/phase-timer.d.ts.map +1 -0
- package/dist/profiler/phase-timer.js +51 -0
- package/dist/profiler/phase-timer.js.map +1 -0
- package/dist/profiler/render-profiler.d.ts +41 -0
- package/dist/profiler/render-profiler.d.ts.map +1 -0
- package/dist/profiler/render-profiler.js +142 -0
- package/dist/profiler/render-profiler.js.map +1 -0
- package/dist/render/components.d.ts +25 -0
- package/dist/render/components.d.ts.map +1 -0
- package/dist/render/components.js +55 -0
- package/dist/render/components.js.map +1 -0
- package/dist/render/emoji-icons.d.ts +5 -0
- package/dist/render/emoji-icons.d.ts.map +1 -0
- package/dist/render/emoji-icons.js +55 -0
- package/dist/render/emoji-icons.js.map +1 -0
- package/dist/render/export-code.d.ts +9 -0
- package/dist/render/export-code.d.ts.map +1 -0
- package/dist/render/export-code.js +335 -0
- package/dist/render/export-code.js.map +1 -0
- package/dist/render/export-jsx.d.ts +5 -0
- package/dist/render/export-jsx.d.ts.map +1 -0
- package/dist/render/export-jsx.js +621 -0
- package/dist/render/export-jsx.js.map +1 -0
- package/dist/render/index.d.ts +8 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +8 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/jsx-runtime.d.ts +31 -0
- package/dist/render/jsx-runtime.d.ts.map +1 -0
- package/dist/render/jsx-runtime.js +13 -0
- package/dist/render/jsx-runtime.js.map +1 -0
- package/dist/render/mini-react.d.ts +14 -0
- package/dist/render/mini-react.d.ts.map +1 -0
- package/dist/render/mini-react.js +16 -0
- package/dist/render/mini-react.js.map +1 -0
- package/dist/render/render-jsx.d.ts +24 -0
- package/dist/render/render-jsx.d.ts.map +1 -0
- package/dist/render/render-jsx.js +51 -0
- package/dist/render/render-jsx.js.map +1 -0
- package/dist/render/renderer.d.ts +16 -0
- package/dist/render/renderer.d.ts.map +1 -0
- package/dist/render/renderer.js +437 -0
- package/dist/render/renderer.js.map +1 -0
- package/dist/render/tailwind.d.ts +20 -0
- package/dist/render/tailwind.d.ts.map +1 -0
- package/dist/render/tailwind.js +115 -0
- package/dist/render/tailwind.js.map +1 -0
- package/dist/render/tree.d.ts +72 -0
- package/dist/render/tree.d.ts.map +1 -0
- package/dist/render/tree.js +63 -0
- package/dist/render/tree.js.map +1 -0
- package/dist/render-image.d.ts +19 -0
- package/dist/render-image.d.ts.map +1 -0
- package/dist/render-image.js +84 -0
- package/dist/render-image.js.map +1 -0
- package/dist/renderer/effects.d.ts +9 -0
- package/dist/renderer/effects.d.ts.map +1 -0
- package/dist/renderer/effects.js +44 -0
- package/dist/renderer/effects.js.map +1 -0
- package/dist/renderer/fills.d.ts +9 -0
- package/dist/renderer/fills.d.ts.map +1 -0
- package/dist/renderer/fills.js +189 -0
- package/dist/renderer/fills.js.map +1 -0
- package/dist/renderer/index.d.ts +2 -0
- package/dist/renderer/index.d.ts.map +1 -0
- package/dist/renderer/index.js +2 -0
- package/dist/renderer/index.js.map +1 -0
- package/dist/renderer/label-cache.d.ts +43 -0
- package/dist/renderer/label-cache.d.ts.map +1 -0
- package/dist/renderer/label-cache.js +85 -0
- package/dist/renderer/label-cache.js.map +1 -0
- package/dist/renderer/labels.d.ts +6 -0
- package/dist/renderer/labels.d.ts.map +1 -0
- package/dist/renderer/labels.js +126 -0
- package/dist/renderer/labels.js.map +1 -0
- package/dist/renderer/lru-cache.d.ts +20 -0
- package/dist/renderer/lru-cache.d.ts.map +1 -0
- package/dist/renderer/lru-cache.js +65 -0
- package/dist/renderer/lru-cache.js.map +1 -0
- package/dist/renderer/overlays.d.ts +25 -0
- package/dist/renderer/overlays.d.ts.map +1 -0
- package/dist/renderer/overlays.js +783 -0
- package/dist/renderer/overlays.js.map +1 -0
- package/dist/renderer/renderer.d.ts +229 -0
- package/dist/renderer/renderer.d.ts.map +1 -0
- package/dist/renderer/renderer.js +909 -0
- package/dist/renderer/renderer.js.map +1 -0
- package/dist/renderer/rulers.d.ts +8 -0
- package/dist/renderer/rulers.d.ts.map +1 -0
- package/dist/renderer/rulers.js +147 -0
- package/dist/renderer/rulers.js.map +1 -0
- package/dist/renderer/scene.d.ts +11 -0
- package/dist/renderer/scene.d.ts.map +1 -0
- package/dist/renderer/scene.js +392 -0
- package/dist/renderer/scene.js.map +1 -0
- package/dist/renderer/shapes.d.ts +13 -0
- package/dist/renderer/shapes.d.ts.map +1 -0
- package/dist/renderer/shapes.js +160 -0
- package/dist/renderer/shapes.js.map +1 -0
- package/dist/renderer/strokes.d.ts +9 -0
- package/dist/renderer/strokes.d.ts.map +1 -0
- package/dist/renderer/strokes.js +180 -0
- package/dist/renderer/strokes.js.map +1 -0
- package/dist/rpc/commands.d.ts +202 -0
- package/dist/rpc/commands.d.ts.map +1 -0
- package/dist/rpc/commands.js +429 -0
- package/dist/rpc/commands.js.map +1 -0
- package/dist/rpc/index.d.ts +3 -0
- package/dist/rpc/index.d.ts.map +1 -0
- package/dist/rpc/index.js +2 -0
- package/dist/rpc/index.js.map +1 -0
- package/dist/scene-graph.d.ts +318 -0
- package/dist/scene-graph.d.ts.map +1 -0
- package/dist/scene-graph.js +803 -0
- package/dist/scene-graph.js.map +1 -0
- package/dist/snap.d.ts +16 -0
- package/dist/snap.d.ts.map +1 -0
- package/dist/snap.js +97 -0
- package/dist/snap.js.map +1 -0
- package/dist/style-runs.d.ts +20 -0
- package/dist/style-runs.d.ts.map +1 -0
- package/dist/style-runs.js +168 -0
- package/dist/style-runs.js.map +1 -0
- package/dist/svg-export/defs.d.ts +19 -0
- package/dist/svg-export/defs.d.ts.map +1 -0
- package/dist/svg-export/defs.js +191 -0
- package/dist/svg-export/defs.js.map +1 -0
- package/dist/svg-export/index.d.ts +8 -0
- package/dist/svg-export/index.d.ts.map +1 -0
- package/dist/svg-export/index.js +318 -0
- package/dist/svg-export/index.js.map +1 -0
- package/dist/svg-export/paths.d.ts +9 -0
- package/dist/svg-export/paths.d.ts.map +1 -0
- package/dist/svg-export/paths.js +189 -0
- package/dist/svg-export/paths.js.map +1 -0
- package/dist/svg-node.d.ts +8 -0
- package/dist/svg-node.d.ts.map +1 -0
- package/dist/svg-node.js +48 -0
- package/dist/svg-node.js.map +1 -0
- package/dist/text-editor.d.ts +57 -0
- package/dist/text-editor.d.ts.map +1 -0
- package/dist/text-editor.js +337 -0
- package/dist/text-editor.js.map +1 -0
- package/dist/tools/ai-adapter.d.ts +22 -0
- package/dist/tools/ai-adapter.d.ts.map +1 -0
- package/dist/tools/ai-adapter.js +121 -0
- package/dist/tools/ai-adapter.js.map +1 -0
- package/dist/tools/analyze.d.ts +22 -0
- package/dist/tools/analyze.d.ts.map +1 -0
- package/dist/tools/analyze.js +677 -0
- package/dist/tools/analyze.js.map +1 -0
- package/dist/tools/create.d.ts +8 -0
- package/dist/tools/create.d.ts.map +1 -0
- package/dist/tools/create.js +204 -0
- package/dist/tools/create.js.map +1 -0
- package/dist/tools/describe.d.ts +9 -0
- package/dist/tools/describe.d.ts.map +1 -0
- package/dist/tools/describe.js +295 -0
- package/dist/tools/describe.js.map +1 -0
- package/dist/tools/export-code.d.ts +2 -0
- package/dist/tools/export-code.d.ts.map +1 -0
- package/dist/tools/export-code.js +34 -0
- package/dist/tools/export-code.js.map +1 -0
- package/dist/tools/export-tailwind-config.d.ts +27 -0
- package/dist/tools/export-tailwind-config.d.ts.map +1 -0
- package/dist/tools/export-tailwind-config.js +215 -0
- package/dist/tools/export-tailwind-config.js.map +1 -0
- package/dist/tools/icons.d.ts +5 -0
- package/dist/tools/icons.d.ts.map +1 -0
- package/dist/tools/icons.js +192 -0
- package/dist/tools/icons.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/modify.d.ts +22 -0
- package/dist/tools/modify.d.ts.map +1 -0
- package/dist/tools/modify.js +653 -0
- package/dist/tools/modify.js.map +1 -0
- package/dist/tools/patterns.d.ts +2 -0
- package/dist/tools/patterns.d.ts.map +1 -0
- package/dist/tools/patterns.js +173 -0
- package/dist/tools/patterns.js.map +1 -0
- package/dist/tools/read.d.ts +17 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +379 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/registry.d.ts +3 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +124 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/schema.d.ts +46 -0
- package/dist/tools/schema.d.ts.map +1 -0
- package/dist/tools/schema.js +17 -0
- package/dist/tools/schema.js.map +1 -0
- package/dist/tools/structure.d.ts +18 -0
- package/dist/tools/structure.d.ts.map +1 -0
- package/dist/tools/structure.js +345 -0
- package/dist/tools/structure.js.map +1 -0
- package/dist/tools/variables.d.ts +12 -0
- package/dist/tools/variables.d.ts.map +1 -0
- package/dist/tools/variables.js +190 -0
- package/dist/tools/variables.js.map +1 -0
- package/dist/tools/vector.d.ts +15 -0
- package/dist/tools/vector.d.ts.map +1 -0
- package/dist/tools/vector.js +312 -0
- package/dist/tools/vector.js.map +1 -0
- package/dist/types.d.ts +29 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/undo.d.ts +33 -0
- package/dist/undo.d.ts.map +1 -0
- package/dist/undo.js +98 -0
- package/dist/undo.js.map +1 -0
- package/dist/vector.d.ts +14 -0
- package/dist/vector.d.ts.map +1 -0
- package/dist/vector.js +334 -0
- package/dist/vector.js.map +1 -0
- package/dist/xpath.d.ts +8 -0
- package/dist/xpath.d.ts.map +1 -0
- package/dist/xpath.js +199 -0
- package/dist/xpath.js.map +1 -0
- package/package.json +54 -0
- package/src/canvaskit.ts +66 -0
- package/src/clipboard.ts +444 -0
- package/src/color.ts +83 -0
- package/src/constants.ts +277 -0
- package/src/copy.ts +75 -0
- package/src/fig-export-worker.ts +28 -0
- package/src/fig-export.ts +321 -0
- package/src/figma-api.ts +1297 -0
- package/src/figma-rest-import.ts +443 -0
- package/src/fonts.ts +369 -0
- package/src/geometry.ts +73 -0
- package/src/global.d.ts +20 -0
- package/src/index.ts +247 -0
- package/src/kiwi/codec.ts +614 -0
- package/src/kiwi/fig-file.ts +248 -0
- package/src/kiwi/fig-import.ts +300 -0
- package/src/kiwi/fig-parse-worker.ts +213 -0
- package/src/kiwi/instance-overrides.ts +682 -0
- package/src/kiwi/kiwi-convert.ts +771 -0
- package/src/kiwi/kiwi-schema/bb.ts +244 -0
- package/src/kiwi/kiwi-schema/binary.ts +102 -0
- package/src/kiwi/kiwi-schema/index.ts +5 -0
- package/src/kiwi/kiwi-schema/js.ts +339 -0
- package/src/kiwi/kiwi-schema/parser.ts +287 -0
- package/src/kiwi/kiwi-schema/schema.ts +24 -0
- package/src/kiwi/kiwi-schema/util.ts +10 -0
- package/src/kiwi/protocol.ts +237 -0
- package/src/kiwi/schema.ts +2286 -0
- package/src/kiwi-serialize.ts +467 -0
- package/src/layout.ts +608 -0
- package/src/profiler/draw-call-counter.ts +43 -0
- package/src/profiler/frame-capture.ts +139 -0
- package/src/profiler/frame-stats.ts +122 -0
- package/src/profiler/gpu-timer.ts +93 -0
- package/src/profiler/hud-renderer.ts +242 -0
- package/src/profiler/index.ts +8 -0
- package/src/profiler/phase-timer.ts +62 -0
- package/src/profiler/render-profiler.ts +163 -0
- package/src/render/components.ts +69 -0
- package/src/render/emoji-icons.ts +60 -0
- package/src/render/export-code.ts +366 -0
- package/src/render/export-jsx.ts +633 -0
- package/src/render/index.ts +38 -0
- package/src/render/jsx-runtime.ts +36 -0
- package/src/render/mini-react.ts +30 -0
- package/src/render/render-jsx.ts +74 -0
- package/src/render/renderer.ts +508 -0
- package/src/render/tailwind.ts +114 -0
- package/src/render/tree.ts +137 -0
- package/src/render-image.ts +139 -0
- package/src/renderer/effects.ts +64 -0
- package/src/renderer/fills.ts +248 -0
- package/src/renderer/index.ts +1 -0
- package/src/renderer/label-cache.ts +114 -0
- package/src/renderer/labels.ts +168 -0
- package/src/renderer/lru-cache.ts +71 -0
- package/src/renderer/overlays.ts +1089 -0
- package/src/renderer/renderer.ts +1226 -0
- package/src/renderer/rulers.ts +230 -0
- package/src/renderer/scene.ts +554 -0
- package/src/renderer/shapes.ts +193 -0
- package/src/renderer/strokes.ts +221 -0
- package/src/rpc/commands.ts +667 -0
- package/src/rpc/index.ts +25 -0
- package/src/scene-graph.ts +1254 -0
- package/src/snap.ts +122 -0
- package/src/style-runs.ts +234 -0
- package/src/svg-export/defs.ts +255 -0
- package/src/svg-export/index.ts +427 -0
- package/src/svg-export/paths.ts +212 -0
- package/src/svg-node.ts +62 -0
- package/src/text-editor.ts +349 -0
- package/src/tools/ai-adapter.ts +144 -0
- package/src/tools/analyze.ts +786 -0
- package/src/tools/create.ts +206 -0
- package/src/tools/describe.ts +280 -0
- package/src/tools/export-code.ts +41 -0
- package/src/tools/export-tailwind-config.ts +266 -0
- package/src/tools/icons.ts +213 -0
- package/src/tools/index.ts +6 -0
- package/src/tools/modify.ts +651 -0
- package/src/tools/patterns.ts +189 -0
- package/src/tools/read.ts +401 -0
- package/src/tools/registry.ts +155 -0
- package/src/tools/schema.ts +65 -0
- package/src/tools/structure.ts +348 -0
- package/src/tools/variables.ts +193 -0
- package/src/tools/vector.ts +311 -0
- package/src/types.ts +32 -0
- package/src/undo.ts +126 -0
- package/src/vector.ts +413 -0
- package/src/xpath.ts +259 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { Schema, Definition, Field, DefinitionKind } from './schema'
|
|
2
|
+
import { error, quote } from './util'
|
|
3
|
+
|
|
4
|
+
export let nativeTypes = ['bool', 'byte', 'float', 'int', 'int64', 'string', 'uint', 'uint64']
|
|
5
|
+
|
|
6
|
+
// These are special names on the object returned by compileSchema()
|
|
7
|
+
export let reservedNames = ['ByteBuffer', 'package']
|
|
8
|
+
|
|
9
|
+
let regex = /((?:-|\b)\d+\b|[=;{}]|\[\]|\[deprecated\]|\b[A-Za-z_][A-Za-z0-9_]*\b|\/\/.*|\s+)/g
|
|
10
|
+
let identifier = /^[A-Za-z_][A-Za-z0-9_]*$/
|
|
11
|
+
let whitespace = /^\/\/.*|\s+$/
|
|
12
|
+
let equals = /^=$/
|
|
13
|
+
let endOfFile = /^$/
|
|
14
|
+
let semicolon = /^;$/
|
|
15
|
+
let integer = /^-?\d+$/
|
|
16
|
+
let leftBrace = /^\{$/
|
|
17
|
+
let rightBrace = /^\}$/
|
|
18
|
+
let arrayToken = /^\[\]$/
|
|
19
|
+
let enumKeyword = /^enum$/
|
|
20
|
+
let structKeyword = /^struct$/
|
|
21
|
+
let messageKeyword = /^message$/
|
|
22
|
+
let packageKeyword = /^package$/
|
|
23
|
+
let deprecatedToken = /^\[deprecated\]$/
|
|
24
|
+
|
|
25
|
+
interface Token {
|
|
26
|
+
text: string
|
|
27
|
+
line: number
|
|
28
|
+
column: number
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function tokenize(text: string): Token[] {
|
|
32
|
+
let parts = text.split(regex)
|
|
33
|
+
let tokens = []
|
|
34
|
+
let column = 0
|
|
35
|
+
let line = 0
|
|
36
|
+
|
|
37
|
+
for (let i = 0; i < parts.length; i++) {
|
|
38
|
+
let part = parts[i]
|
|
39
|
+
|
|
40
|
+
// Keep non-whitespace tokens
|
|
41
|
+
if (i & 1) {
|
|
42
|
+
if (!whitespace.test(part)) {
|
|
43
|
+
tokens.push({
|
|
44
|
+
text: part,
|
|
45
|
+
line: line + 1,
|
|
46
|
+
column: column + 1
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Detect syntax errors
|
|
52
|
+
else if (part !== '') {
|
|
53
|
+
error('Syntax error ' + quote(part), line + 1, column + 1)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Keep track of the line and column counts
|
|
57
|
+
let lines = part.split('\n')
|
|
58
|
+
if (lines.length > 1) column = 0
|
|
59
|
+
line += lines.length - 1
|
|
60
|
+
column += lines[lines.length - 1].length
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// End-of-file token
|
|
64
|
+
tokens.push({
|
|
65
|
+
text: '',
|
|
66
|
+
line: line,
|
|
67
|
+
column: column
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
return tokens
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function parse(tokens: Token[]): Schema {
|
|
74
|
+
function current(): Token {
|
|
75
|
+
return tokens[index]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function eat(test: RegExp): boolean {
|
|
79
|
+
if (test.test(current().text)) {
|
|
80
|
+
index++
|
|
81
|
+
return true
|
|
82
|
+
}
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function expect(test: RegExp, expected: string): void {
|
|
87
|
+
if (!eat(test)) {
|
|
88
|
+
let token = current()
|
|
89
|
+
error('Expected ' + expected + ' but found ' + quote(token.text), token.line, token.column)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function unexpectedToken(): never {
|
|
94
|
+
let token = current()
|
|
95
|
+
error('Unexpected token ' + quote(token.text), token.line, token.column)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let definitions: Definition[] = []
|
|
99
|
+
let packageText = null
|
|
100
|
+
let index = 0
|
|
101
|
+
|
|
102
|
+
if (eat(packageKeyword)) {
|
|
103
|
+
packageText = current().text
|
|
104
|
+
expect(identifier, 'identifier')
|
|
105
|
+
expect(semicolon, '";"')
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
while (index < tokens.length && !eat(endOfFile)) {
|
|
109
|
+
let fields: Field[] = []
|
|
110
|
+
let kind: DefinitionKind
|
|
111
|
+
|
|
112
|
+
if (eat(enumKeyword)) kind = 'ENUM'
|
|
113
|
+
else if (eat(structKeyword)) kind = 'STRUCT'
|
|
114
|
+
else if (eat(messageKeyword)) kind = 'MESSAGE'
|
|
115
|
+
else unexpectedToken()
|
|
116
|
+
|
|
117
|
+
// All definitions start off the same
|
|
118
|
+
let name = current()
|
|
119
|
+
expect(identifier, 'identifier')
|
|
120
|
+
expect(leftBrace, '"{"')
|
|
121
|
+
|
|
122
|
+
// Parse fields
|
|
123
|
+
while (!eat(rightBrace)) {
|
|
124
|
+
let type: string | null = null
|
|
125
|
+
let isArray = false
|
|
126
|
+
let isDeprecated = false
|
|
127
|
+
|
|
128
|
+
// Enums don't have types
|
|
129
|
+
if (kind !== 'ENUM') {
|
|
130
|
+
type = current().text
|
|
131
|
+
expect(identifier, 'identifier')
|
|
132
|
+
isArray = eat(arrayToken)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let field = current()
|
|
136
|
+
expect(identifier, 'identifier')
|
|
137
|
+
|
|
138
|
+
// Structs don't have explicit values
|
|
139
|
+
let value: Token | null = null
|
|
140
|
+
if (kind !== 'STRUCT') {
|
|
141
|
+
expect(equals, '"="')
|
|
142
|
+
value = current()
|
|
143
|
+
expect(integer, 'integer')
|
|
144
|
+
|
|
145
|
+
if ((+value.text | 0) + '' !== value.text) {
|
|
146
|
+
error('Invalid integer ' + quote(value.text), value.line, value.column)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
let deprecated = current()
|
|
151
|
+
if (eat(deprecatedToken)) {
|
|
152
|
+
if (kind !== 'MESSAGE') {
|
|
153
|
+
error('Cannot deprecate this field', deprecated.line, deprecated.column)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
isDeprecated = true
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
expect(semicolon, '";"')
|
|
160
|
+
|
|
161
|
+
fields.push({
|
|
162
|
+
name: field.text,
|
|
163
|
+
line: field.line,
|
|
164
|
+
column: field.column,
|
|
165
|
+
type: type,
|
|
166
|
+
isArray: isArray,
|
|
167
|
+
isDeprecated: isDeprecated,
|
|
168
|
+
value: value !== null ? +value.text | 0 : fields.length + 1
|
|
169
|
+
})
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
definitions.push({
|
|
173
|
+
name: name.text,
|
|
174
|
+
line: name.line,
|
|
175
|
+
column: name.column,
|
|
176
|
+
kind: kind,
|
|
177
|
+
fields: fields
|
|
178
|
+
})
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
package: packageText,
|
|
183
|
+
definitions: definitions
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function verify(root: Schema): void {
|
|
188
|
+
let definedTypes = nativeTypes.slice()
|
|
189
|
+
let definitions: { [name: string]: Definition } = {}
|
|
190
|
+
|
|
191
|
+
// Define definitions
|
|
192
|
+
for (let i = 0; i < root.definitions.length; i++) {
|
|
193
|
+
let definition = root.definitions[i]
|
|
194
|
+
if (definedTypes.indexOf(definition.name) !== -1) {
|
|
195
|
+
error(
|
|
196
|
+
'The type ' + quote(definition.name) + ' is defined twice',
|
|
197
|
+
definition.line,
|
|
198
|
+
definition.column
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
if (reservedNames.indexOf(definition.name) !== -1) {
|
|
202
|
+
error(
|
|
203
|
+
'The type name ' + quote(definition.name) + ' is reserved',
|
|
204
|
+
definition.line,
|
|
205
|
+
definition.column
|
|
206
|
+
)
|
|
207
|
+
}
|
|
208
|
+
definedTypes.push(definition.name)
|
|
209
|
+
definitions[definition.name] = definition
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Check fields
|
|
213
|
+
for (let i = 0; i < root.definitions.length; i++) {
|
|
214
|
+
let definition = root.definitions[i]
|
|
215
|
+
let fields = definition.fields
|
|
216
|
+
|
|
217
|
+
if (definition.kind === 'ENUM' || fields.length === 0) {
|
|
218
|
+
continue
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Check types
|
|
222
|
+
for (let j = 0; j < fields.length; j++) {
|
|
223
|
+
let field = fields[j]
|
|
224
|
+
if (definedTypes.indexOf(field.type!) === -1) {
|
|
225
|
+
error(
|
|
226
|
+
'The type ' + quote(field.type!) + ' is not defined for field ' + quote(field.name),
|
|
227
|
+
field.line,
|
|
228
|
+
field.column
|
|
229
|
+
)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Check values
|
|
234
|
+
let values: number[] = []
|
|
235
|
+
for (let j = 0; j < fields.length; j++) {
|
|
236
|
+
let field = fields[j]
|
|
237
|
+
if (values.indexOf(field.value) !== -1) {
|
|
238
|
+
error('The id for field ' + quote(field.name) + ' is used twice', field.line, field.column)
|
|
239
|
+
}
|
|
240
|
+
if (field.value <= 0) {
|
|
241
|
+
error(
|
|
242
|
+
'The id for field ' + quote(field.name) + ' must be positive',
|
|
243
|
+
field.line,
|
|
244
|
+
field.column
|
|
245
|
+
)
|
|
246
|
+
}
|
|
247
|
+
// Figma schema uses sparse field IDs (up to 435), so skip sequential check
|
|
248
|
+
values.push(field.value)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Check that structs don't contain themselves
|
|
253
|
+
let state: { [name: string]: number } = {}
|
|
254
|
+
let check = (name: string): boolean => {
|
|
255
|
+
let definition = definitions[name]
|
|
256
|
+
if (definition && definition.kind === 'STRUCT') {
|
|
257
|
+
if (state[name] === 1) {
|
|
258
|
+
error(
|
|
259
|
+
'Recursive nesting of ' + quote(name) + ' is not allowed',
|
|
260
|
+
definition.line,
|
|
261
|
+
definition.column
|
|
262
|
+
)
|
|
263
|
+
}
|
|
264
|
+
if (state[name] !== 2 && definition) {
|
|
265
|
+
state[name] = 1
|
|
266
|
+
let fields = definition.fields
|
|
267
|
+
for (let i = 0; i < fields.length; i++) {
|
|
268
|
+
let field = fields[i]
|
|
269
|
+
if (!field.isArray) {
|
|
270
|
+
check(field.type!)
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
state[name] = 2
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return true
|
|
277
|
+
}
|
|
278
|
+
for (let i = 0; i < root.definitions.length; i++) {
|
|
279
|
+
check(root.definitions[i].name)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export function parseSchema(text: string): Schema {
|
|
284
|
+
let schema = parse(tokenize(text))
|
|
285
|
+
verify(schema)
|
|
286
|
+
return schema
|
|
287
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface Schema {
|
|
2
|
+
package: string | null
|
|
3
|
+
definitions: Definition[]
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export type DefinitionKind = 'ENUM' | 'STRUCT' | 'MESSAGE'
|
|
7
|
+
|
|
8
|
+
export interface Definition {
|
|
9
|
+
name: string
|
|
10
|
+
line: number
|
|
11
|
+
column: number
|
|
12
|
+
kind: DefinitionKind
|
|
13
|
+
fields: Field[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface Field {
|
|
17
|
+
name: string
|
|
18
|
+
line: number
|
|
19
|
+
column: number
|
|
20
|
+
type: string | null
|
|
21
|
+
isArray: boolean
|
|
22
|
+
isDeprecated: boolean
|
|
23
|
+
value: number
|
|
24
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function quote(text: string): string {
|
|
2
|
+
return JSON.stringify(text)
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function error(text: string, line: number, column: number): never {
|
|
6
|
+
var error = new Error(text)
|
|
7
|
+
;(error as any).line = line
|
|
8
|
+
;(error as any).column = column
|
|
9
|
+
throw error
|
|
10
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma Multiplayer Protocol
|
|
3
|
+
*
|
|
4
|
+
* This module handles the low-level WebSocket communication with Figma's
|
|
5
|
+
* multiplayer server. The protocol uses:
|
|
6
|
+
*
|
|
7
|
+
* - Kiwi binary serialization (schema-based, like Protocol Buffers)
|
|
8
|
+
* - Zstd compression for all messages
|
|
9
|
+
* - Session-based authentication via cookies
|
|
10
|
+
*
|
|
11
|
+
* Message types (from Figma's schema):
|
|
12
|
+
* 0 = JOIN_START - Server sends session info
|
|
13
|
+
* 1 = NODE_CHANGES - Create/update/delete nodes
|
|
14
|
+
* 2 = USER_CHANGES - User presence updates
|
|
15
|
+
* 3 = JOIN_END - Initial sync complete
|
|
16
|
+
* 4 = SIGNAL - Various metadata (reconnect info, etc.)
|
|
17
|
+
* 5 = STYLE - Style updates
|
|
18
|
+
* ...and more
|
|
19
|
+
*
|
|
20
|
+
* Wire format:
|
|
21
|
+
* All messages are Zstd-compressed Kiwi-encoded binary data.
|
|
22
|
+
* Zstd magic bytes: 0x28 0xB5 0x2F 0xFD
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export const MESSAGE_TYPES = {
|
|
26
|
+
JOIN_START: 0,
|
|
27
|
+
NODE_CHANGES: 1,
|
|
28
|
+
USER_CHANGES: 2,
|
|
29
|
+
JOIN_END: 3,
|
|
30
|
+
SIGNAL: 4,
|
|
31
|
+
STYLE: 5,
|
|
32
|
+
STYLE_SET: 6,
|
|
33
|
+
JOIN_START_SKIP_RELOAD: 7,
|
|
34
|
+
NOTIFY_SHOULD_UPGRADE: 8,
|
|
35
|
+
UPGRADE_DONE: 9,
|
|
36
|
+
UPGRADE_REFRESH: 10,
|
|
37
|
+
SCENE_GRAPH_QUERY: 11,
|
|
38
|
+
SCENE_GRAPH_REPLY: 12,
|
|
39
|
+
DIFF: 13,
|
|
40
|
+
CLIENT_BROADCAST: 14
|
|
41
|
+
} as const
|
|
42
|
+
|
|
43
|
+
export const NODE_TYPES = {
|
|
44
|
+
NONE: 0,
|
|
45
|
+
DOCUMENT: 1,
|
|
46
|
+
CANVAS: 2,
|
|
47
|
+
GROUP: 3,
|
|
48
|
+
FRAME: 4,
|
|
49
|
+
BOOLEAN_OPERATION: 5,
|
|
50
|
+
VECTOR: 6,
|
|
51
|
+
STAR: 7,
|
|
52
|
+
LINE: 8,
|
|
53
|
+
ELLIPSE: 9,
|
|
54
|
+
RECTANGLE: 10,
|
|
55
|
+
REGULAR_POLYGON: 11,
|
|
56
|
+
ROUNDED_RECTANGLE: 12,
|
|
57
|
+
TEXT: 13,
|
|
58
|
+
SLICE: 14,
|
|
59
|
+
SYMBOL: 15,
|
|
60
|
+
INSTANCE: 16,
|
|
61
|
+
STICKY: 17,
|
|
62
|
+
SHAPE_WITH_TEXT: 18,
|
|
63
|
+
CONNECTOR: 19,
|
|
64
|
+
CODE_BLOCK: 20,
|
|
65
|
+
WIDGET: 21,
|
|
66
|
+
STAMP: 22,
|
|
67
|
+
MEDIA: 23,
|
|
68
|
+
HIGHLIGHT: 24,
|
|
69
|
+
SECTION: 25,
|
|
70
|
+
SECTION_OVERLAY: 26,
|
|
71
|
+
WASHI_TAPE: 27,
|
|
72
|
+
VARIABLE: 28
|
|
73
|
+
} as const
|
|
74
|
+
|
|
75
|
+
export const NODE_PHASES = {
|
|
76
|
+
CREATED: 0,
|
|
77
|
+
REMOVED: 1
|
|
78
|
+
} as const
|
|
79
|
+
|
|
80
|
+
export const BLEND_MODES = {
|
|
81
|
+
PASS_THROUGH: 0,
|
|
82
|
+
NORMAL: 1,
|
|
83
|
+
DARKEN: 2,
|
|
84
|
+
MULTIPLY: 3,
|
|
85
|
+
LINEAR_BURN: 4,
|
|
86
|
+
COLOR_BURN: 5,
|
|
87
|
+
LIGHTEN: 6,
|
|
88
|
+
SCREEN: 7,
|
|
89
|
+
LINEAR_DODGE: 8,
|
|
90
|
+
COLOR_DODGE: 9,
|
|
91
|
+
OVERLAY: 10,
|
|
92
|
+
SOFT_LIGHT: 11,
|
|
93
|
+
HARD_LIGHT: 12,
|
|
94
|
+
DIFFERENCE: 13,
|
|
95
|
+
EXCLUSION: 14,
|
|
96
|
+
HUE: 15,
|
|
97
|
+
SATURATION: 16,
|
|
98
|
+
COLOR: 17,
|
|
99
|
+
LUMINOSITY: 18
|
|
100
|
+
} as const
|
|
101
|
+
|
|
102
|
+
export const PAINT_TYPES = {
|
|
103
|
+
SOLID: 0,
|
|
104
|
+
GRADIENT_LINEAR: 1,
|
|
105
|
+
GRADIENT_RADIAL: 2,
|
|
106
|
+
GRADIENT_ANGULAR: 3,
|
|
107
|
+
GRADIENT_DIAMOND: 4,
|
|
108
|
+
IMAGE: 5,
|
|
109
|
+
EMOJI: 6,
|
|
110
|
+
VIDEO: 7
|
|
111
|
+
} as const
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Zstd magic bytes
|
|
115
|
+
*/
|
|
116
|
+
export const ZSTD_MAGIC = new Uint8Array([0x28, 0xb5, 0x2f, 0xfd])
|
|
117
|
+
|
|
118
|
+
// ============================================================================
|
|
119
|
+
// Kiwi Binary Format Constants
|
|
120
|
+
// ============================================================================
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Kiwi uses field numbers to identify message fields.
|
|
124
|
+
* Field 1 with value = message type indicates the message kind.
|
|
125
|
+
*/
|
|
126
|
+
export const KIWI = {
|
|
127
|
+
/** First byte of valid Kiwi messages (field number 1) */
|
|
128
|
+
MESSAGE_MARKER: 1,
|
|
129
|
+
|
|
130
|
+
/** Field number for sessionID in JOIN_START message */
|
|
131
|
+
SESSION_ID_FIELD: 2,
|
|
132
|
+
|
|
133
|
+
/** Varint continuation bit (MSB set = more bytes follow) */
|
|
134
|
+
VARINT_CONTINUE_BIT: 0x80,
|
|
135
|
+
|
|
136
|
+
/** Varint value mask (lower 7 bits contain data) */
|
|
137
|
+
VARINT_VALUE_MASK: 0x7f,
|
|
138
|
+
|
|
139
|
+
/** Bits per varint byte */
|
|
140
|
+
VARINT_BITS_PER_BYTE: 7
|
|
141
|
+
} as const
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Valid session ID range (based on observed Figma behavior)
|
|
145
|
+
*/
|
|
146
|
+
export const SESSION_ID = {
|
|
147
|
+
MIN: 10000,
|
|
148
|
+
MAX: 1000000
|
|
149
|
+
} as const
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Parse a varint from a Uint8Array at given position
|
|
153
|
+
* Returns [value, newPosition]
|
|
154
|
+
*/
|
|
155
|
+
export function parseVarint(data: Uint8Array, pos: number): [number, number] {
|
|
156
|
+
let value = 0
|
|
157
|
+
let shift = 0
|
|
158
|
+
|
|
159
|
+
while (pos < data.length) {
|
|
160
|
+
const byte = data[pos]
|
|
161
|
+
pos++
|
|
162
|
+
value |= (byte & KIWI.VARINT_VALUE_MASK) << shift
|
|
163
|
+
|
|
164
|
+
if (!(byte & KIWI.VARINT_CONTINUE_BIT)) {
|
|
165
|
+
break
|
|
166
|
+
}
|
|
167
|
+
shift += KIWI.VARINT_BITS_PER_BYTE
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return [value, pos]
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Check if data is a valid Kiwi message
|
|
175
|
+
*/
|
|
176
|
+
export function isKiwiMessage(data: Uint8Array): boolean {
|
|
177
|
+
return data.length >= 2 && data[0] === KIWI.MESSAGE_MARKER
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Get message type from Kiwi message
|
|
182
|
+
*/
|
|
183
|
+
export function getKiwiMessageType(data: Uint8Array): number | null {
|
|
184
|
+
if (!isKiwiMessage(data)) return null
|
|
185
|
+
return data[1] ?? null
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* fig-wire header magic (first 8 bytes of some messages)
|
|
190
|
+
*/
|
|
191
|
+
export const FIG_WIRE_MAGIC = 'fig-wire'
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Check if data is Zstd-compressed
|
|
195
|
+
*/
|
|
196
|
+
export function isZstdCompressed(data: Uint8Array): boolean {
|
|
197
|
+
return (
|
|
198
|
+
data.length >= 4 && data[0] === 0x28 && data[1] === 0xb5 && data[2] === 0x2f && data[3] === 0xfd
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Check if data has fig-wire header
|
|
204
|
+
*/
|
|
205
|
+
export function hasFigWireHeader(data: Uint8Array): boolean {
|
|
206
|
+
if (data.length < 8) return false
|
|
207
|
+
const header = new TextDecoder().decode(data.slice(0, 8))
|
|
208
|
+
return header === FIG_WIRE_MAGIC
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Skip fig-wire header and find zstd data
|
|
213
|
+
* Header format: "fig-wire" (8 bytes) + version (4 bytes LE) + zstd data
|
|
214
|
+
*/
|
|
215
|
+
export function skipFigWireHeader(data: Uint8Array): Uint8Array {
|
|
216
|
+
if (!hasFigWireHeader(data)) return data
|
|
217
|
+
// Skip 8 bytes header + 4 bytes version
|
|
218
|
+
return data.slice(12)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Current multiplayer protocol version
|
|
223
|
+
*/
|
|
224
|
+
export const PROTOCOL_VERSION = 151
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Build WebSocket URL for Figma multiplayer
|
|
228
|
+
*/
|
|
229
|
+
export function buildMultiplayerUrl(fileKey: string, trackingId?: string): string {
|
|
230
|
+
const params = new URLSearchParams({
|
|
231
|
+
role: 'editor',
|
|
232
|
+
version: String(PROTOCOL_VERSION),
|
|
233
|
+
recentReload: '0',
|
|
234
|
+
tracking_session_id: trackingId || `ws-${Date.now()}`
|
|
235
|
+
})
|
|
236
|
+
return `wss://www.figma.com/api/multiplayer/${fileKey}?${params}`
|
|
237
|
+
}
|