@flowgram-vue/core 0.2.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.
Files changed (133) hide show
  1. package/LICENSE +22 -0
  2. package/dist/index.cjs +0 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +0 -0
  6. package/dist/index.js.map +1 -0
  7. package/package.json +63 -0
  8. package/src/common/config-entity.ts +80 -0
  9. package/src/common/entity-data.ts +171 -0
  10. package/src/common/entity-manager-contribution.ts +12 -0
  11. package/src/common/entity-manager.ts +475 -0
  12. package/src/common/entity.ts +482 -0
  13. package/src/common/index.ts +22 -0
  14. package/src/common/playground-context.ts +35 -0
  15. package/src/common/playground-decorator-helper.ts +113 -0
  16. package/src/common/playground-decorators.ts +85 -0
  17. package/src/common/playground-schedule.ts +30 -0
  18. package/src/common/protect-wheel-area.ts +11 -0
  19. package/src/common/schema/index.ts +14 -0
  20. package/src/common/schema/node.ts +15 -0
  21. package/src/common/schema/opacity-schema.ts +19 -0
  22. package/src/common/schema/origin-schema.ts +35 -0
  23. package/src/common/schema/position-schema.ts +35 -0
  24. package/src/common/schema/rotation-schema.ts +19 -0
  25. package/src/common/schema/scale-schema.ts +35 -0
  26. package/src/common/schema/size-schema.ts +42 -0
  27. package/src/common/schema/skew-schema.ts +35 -0
  28. package/src/common/schema/transform-schema.ts +613 -0
  29. package/src/common/utils/bounds.spec.ts +229 -0
  30. package/src/common/utils/bounds.ts +176 -0
  31. package/src/common/utils/index.ts +6 -0
  32. package/src/composables/index.ts +16 -0
  33. package/src/composables/use-config-entity.ts +31 -0
  34. package/src/composables/use-entities.ts +26 -0
  35. package/src/composables/use-entity-data-from-context.ts +34 -0
  36. package/src/composables/use-entity-from-context.ts +31 -0
  37. package/src/composables/use-listen-events.ts +22 -0
  38. package/src/composables/use-playground-container.ts +16 -0
  39. package/src/composables/use-playground-context.ts +15 -0
  40. package/src/composables/use-playground-drag.ts +31 -0
  41. package/src/composables/use-playground.ts +16 -0
  42. package/src/composables/use-refresh.ts +6 -0
  43. package/src/composables/use-service.ts +17 -0
  44. package/src/core/index.ts +8 -0
  45. package/src/core/layer/config/editor-state-config-entity.ts +180 -0
  46. package/src/core/layer/config/index.ts +7 -0
  47. package/src/core/layer/config/playground-config-entity.ts +604 -0
  48. package/src/core/layer/index.ts +8 -0
  49. package/src/core/layer/layer.ts +248 -0
  50. package/src/core/layer/playground-layer.ts +547 -0
  51. package/src/core/pipeline/index.ts +10 -0
  52. package/src/core/pipeline/pipeline-entities-selector.ts +200 -0
  53. package/src/core/pipeline/pipeline-entities.ts +230 -0
  54. package/src/core/pipeline/pipeline-registry.ts +344 -0
  55. package/src/core/pipeline/pipeline-renderer.ts +248 -0
  56. package/src/core/pipeline/pipeline-vue-utils.ts +96 -0
  57. package/src/core/pipeline/pipeline.ts +28 -0
  58. package/src/core/utils/index.ts +12 -0
  59. package/src/core/utils/inject-provider-decorators.ts +27 -0
  60. package/src/core/utils/lazy-inject-decorators.ts +38 -0
  61. package/src/core/utils/mouse-touch-event.ts +120 -0
  62. package/src/core/utils/playground-drag.ts +511 -0
  63. package/src/core/utils/playground-gesture.spec.ts +135 -0
  64. package/src/core/utils/playground-gesture.ts +118 -0
  65. package/src/core/utils/tween.ts +156 -0
  66. package/src/core/utils/use-gesture/core/Controller.ts +212 -0
  67. package/src/core/utils/use-gesture/core/EventStore.ts +46 -0
  68. package/src/core/utils/use-gesture/core/TimeoutStore.ts +28 -0
  69. package/src/core/utils/use-gesture/core/actions.ts +63 -0
  70. package/src/core/utils/use-gesture/core/config/commonConfigResolver.ts +86 -0
  71. package/src/core/utils/use-gesture/core/config/coordinatesConfigResolver.ts +48 -0
  72. package/src/core/utils/use-gesture/core/config/dragConfigResolver.ts +140 -0
  73. package/src/core/utils/use-gesture/core/config/hoverConfigResolver.ts +11 -0
  74. package/src/core/utils/use-gesture/core/config/moveConfigResolver.ts +11 -0
  75. package/src/core/utils/use-gesture/core/config/pinchConfigResolver.ts +59 -0
  76. package/src/core/utils/use-gesture/core/config/resolver.ts +70 -0
  77. package/src/core/utils/use-gesture/core/config/scrollConfigResolver.ts +8 -0
  78. package/src/core/utils/use-gesture/core/config/sharedConfigResolver.ts +28 -0
  79. package/src/core/utils/use-gesture/core/config/support.ts +52 -0
  80. package/src/core/utils/use-gesture/core/config/wheelConfigResolver.ts +8 -0
  81. package/src/core/utils/use-gesture/core/engines/CoordinatesEngine.ts +78 -0
  82. package/src/core/utils/use-gesture/core/engines/DragEngine.ts +403 -0
  83. package/src/core/utils/use-gesture/core/engines/Engine.ts +406 -0
  84. package/src/core/utils/use-gesture/core/engines/HoverEngine.ts +43 -0
  85. package/src/core/utils/use-gesture/core/engines/MoveEngine.ts +52 -0
  86. package/src/core/utils/use-gesture/core/engines/PinchEngine.ts +345 -0
  87. package/src/core/utils/use-gesture/core/engines/ScrollEngine.ts +42 -0
  88. package/src/core/utils/use-gesture/core/engines/WheelEngine.ts +48 -0
  89. package/src/core/utils/use-gesture/core/index.ts +7 -0
  90. package/src/core/utils/use-gesture/core/parser.ts +92 -0
  91. package/src/core/utils/use-gesture/core/types/action.ts +19 -0
  92. package/src/core/utils/use-gesture/core/types/config.ts +255 -0
  93. package/src/core/utils/use-gesture/core/types/handlers.ts +73 -0
  94. package/src/core/utils/use-gesture/core/types/index.ts +11 -0
  95. package/src/core/utils/use-gesture/core/types/internalConfig.ts +80 -0
  96. package/src/core/utils/use-gesture/core/types/state.ts +275 -0
  97. package/src/core/utils/use-gesture/core/types/utils.ts +204 -0
  98. package/src/core/utils/use-gesture/core/types.ts +8 -0
  99. package/src/core/utils/use-gesture/core/utils/events.ts +158 -0
  100. package/src/core/utils/use-gesture/core/utils/fn.ts +32 -0
  101. package/src/core/utils/use-gesture/core/utils/maths.ts +63 -0
  102. package/src/core/utils/use-gesture/core/utils/state.ts +24 -0
  103. package/src/core/utils/use-gesture/core/utils.ts +8 -0
  104. package/src/core/utils/use-gesture/index.ts +6 -0
  105. package/src/core/utils/use-gesture/vanilla/DragGesture.ts +27 -0
  106. package/src/core/utils/use-gesture/vanilla/Gesture.ts +45 -0
  107. package/src/core/utils/use-gesture/vanilla/HoverGesture.ts +27 -0
  108. package/src/core/utils/use-gesture/vanilla/MoveGesture.ts +27 -0
  109. package/src/core/utils/use-gesture/vanilla/PinchGesture.ts +27 -0
  110. package/src/core/utils/use-gesture/vanilla/Recognizer.ts +43 -0
  111. package/src/core/utils/use-gesture/vanilla/ScrollGesture.ts +27 -0
  112. package/src/core/utils/use-gesture/vanilla/WheelGesture.ts +27 -0
  113. package/src/core/utils/use-gesture/vanilla/createGesture.ts +18 -0
  114. package/src/core/utils/use-gesture/vanilla/index.ts +18 -0
  115. package/src/env.d.ts +10 -0
  116. package/src/index.ts +17 -0
  117. package/src/playground-config.ts +70 -0
  118. package/src/playground-container.ts +129 -0
  119. package/src/playground-contribution.ts +81 -0
  120. package/src/playground-mock-tools.ts +143 -0
  121. package/src/playground.ts +401 -0
  122. package/src/plugin/index.ts +6 -0
  123. package/src/plugin/plugin.ts +226 -0
  124. package/src/services/clipboard-service.ts +40 -0
  125. package/src/services/context-menu-service.ts +25 -0
  126. package/src/services/index.ts +10 -0
  127. package/src/services/logger-service.ts +49 -0
  128. package/src/services/selection-service.ts +54 -0
  129. package/src/services/storage-service.ts +65 -0
  130. package/src/vue/index.ts +8 -0
  131. package/src/vue/playground-vue-context.ts +22 -0
  132. package/src/vue/playground-vue-provider.ts +115 -0
  133. package/src/vue/playground-vue-renderer.vue +44 -0
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { injectable } from 'inversify';
7
+ import { type Disposable, Emitter, type Event } from '@flowgram-vue/utils';
8
+
9
+ export interface LoggerProps {
10
+ event: LoggerEvent;
11
+ props?: Record<string, any>;
12
+ }
13
+
14
+ export enum LoggerEvent {
15
+ CANVAS_TTI, // Time To Interactive,画布可交互时间
16
+ CANVAS_FPS, // Frame Per Second,画布渲染帧率
17
+ }
18
+
19
+ /**
20
+ * 画布全局的选择器,可以放任何东西
21
+ */
22
+ @injectable()
23
+ export class LoggerService implements Disposable {
24
+ protected readonly onLoggerEmitter = new Emitter<LoggerProps>();
25
+
26
+ // plugin 内注册:loggerService.onLogger(() => {})
27
+ readonly onLogger: Event<any> = this.onLoggerEmitter.event;
28
+
29
+ onAllLayersRendered() {
30
+ this.onLoggerEmitter.fire({
31
+ event: LoggerEvent.CANVAS_TTI,
32
+ });
33
+ }
34
+
35
+ onFlushRequest(renderFrameInterval: number) {
36
+ if (renderFrameInterval <= 0) {
37
+ return;
38
+ }
39
+ const fps = 1000 / renderFrameInterval;
40
+ this.onLoggerEmitter.fire({
41
+ event: LoggerEvent.CANVAS_FPS,
42
+ props: { rfi: renderFrameInterval, fps },
43
+ });
44
+ }
45
+
46
+ dispose() {
47
+ this.onLoggerEmitter.dispose();
48
+ }
49
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { injectable } from 'inversify';
7
+ import { Compare, type Disposable, Emitter, type Event } from '@flowgram-vue/utils';
8
+
9
+ import { type Entity } from '../common';
10
+
11
+ /**
12
+ * 画布全局的选择器,可以放任何东西
13
+ */
14
+ @injectable()
15
+ export class SelectionService implements Disposable {
16
+ protected readonly onSelectionChangedEmitter = new Emitter<Entity[]>();
17
+
18
+ readonly onSelectionChanged: Event<any> = this.onSelectionChangedEmitter.event;
19
+
20
+ private currentSelection: Entity[] = [];
21
+
22
+ private disposers: Disposable[] = [];
23
+
24
+ get selection(): Entity[] {
25
+ return this.currentSelection;
26
+ }
27
+
28
+ isEmpty(): boolean {
29
+ return this.currentSelection.length === 0;
30
+ }
31
+
32
+ set selection(selection: Entity<any>[]) {
33
+ if (!Compare.isArrayShallowChanged(this.currentSelection, selection)) {
34
+ return;
35
+ }
36
+ this.disposers.forEach((disposer) => disposer.dispose());
37
+ this.changeSelection(selection);
38
+ this.disposers = this.currentSelection.map((selection) =>
39
+ selection.onDispose(() => {
40
+ const newSelection = this.currentSelection.filter((n) => n !== selection);
41
+ this.changeSelection(newSelection);
42
+ })
43
+ );
44
+ }
45
+
46
+ private changeSelection(selection: Entity<any>[]) {
47
+ this.currentSelection = selection;
48
+ this.onSelectionChangedEmitter.fire(this.currentSelection);
49
+ }
50
+
51
+ dispose() {
52
+ this.onSelectionChangedEmitter.dispose();
53
+ }
54
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { injectable, postConstruct } from 'inversify';
7
+
8
+ export const StorageService = Symbol('StorageService');
9
+
10
+ /**
11
+ * 存储数据到缓存
12
+ */
13
+ export interface StorageService {
14
+ /**
15
+ * Stores the given data under the given key.
16
+ */
17
+ setData<T>(key: string, data: T): void;
18
+
19
+ /**
20
+ * Returns the data stored for the given key or the provided default value if nothing is stored for the given key.
21
+ */
22
+ getData<T>(key: string, defaultValue: T): T;
23
+
24
+ getData<T>(key: string): T | undefined;
25
+ }
26
+
27
+ interface LocalStorage {
28
+ [key: string]: any;
29
+ }
30
+
31
+ @injectable()
32
+ export class LocalStorageService implements StorageService {
33
+ private storage: LocalStorage;
34
+
35
+ private _prefix = '__gedit:';
36
+
37
+ setData<T>(key: string, data: T): void {
38
+ this.storage[this.prefix(key)] = JSON.stringify(data);
39
+ }
40
+
41
+ getData<T>(key: string, defaultValue?: T): T {
42
+ const result = this.storage[this.prefix(key)];
43
+ if (result === undefined) {
44
+ return defaultValue as any;
45
+ }
46
+ return JSON.parse(result);
47
+ }
48
+
49
+ prefix(key: string) {
50
+ return `${this._prefix}${key}`;
51
+ }
52
+
53
+ setPrefix(prefix: string) {
54
+ this._prefix = prefix;
55
+ }
56
+
57
+ @postConstruct()
58
+ protected init(): void {
59
+ if (typeof window !== 'undefined' && window.localStorage) {
60
+ this.storage = window.localStorage;
61
+ } else {
62
+ this.storage = {};
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export * from './playground-vue-context';
7
+ export * from './playground-vue-provider';
8
+ export { default as PlaygroundVueRenderer } from './playground-vue-renderer.vue';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import type { interfaces } from 'inversify';
7
+ import type { InjectionKey } from 'vue';
8
+
9
+ import type { Playground } from '../playground';
10
+
11
+ export const PlaygroundVueContextKey: InjectionKey<any> = Symbol('PlaygroundVueContext');
12
+
13
+ export const PlaygroundVueContainerKey: InjectionKey<interfaces.Container> = Symbol(
14
+ 'PlaygroundVueContainer'
15
+ );
16
+
17
+ export const PlaygroundVueRefKey: InjectionKey<Playground> = Symbol('PlaygroundVueRef');
18
+
19
+ /**
20
+ * 当前 entity
21
+ */
22
+ export const PlaygroundEntityContextKey: InjectionKey<any> = Symbol('PlaygroundEntityContext');
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { type interfaces } from 'inversify';
7
+ import { defineComponent, onBeforeUnmount, onMounted, provide, type PropType } from 'vue';
8
+
9
+ import { PluginContext, loadPlugins, type PluginsProvider } from '../plugin';
10
+ import { createPlaygroundContainer } from '../playground-container';
11
+ import { Playground } from '../playground';
12
+ import { PlaygroundContext } from '../common';
13
+ import {
14
+ PlaygroundVueContainerKey,
15
+ PlaygroundVueContextKey,
16
+ PlaygroundVueRefKey,
17
+ } from './playground-vue-context';
18
+
19
+ export interface PlaygroundVueProviderProps {
20
+ containerModules?: interfaces.ContainerModule[];
21
+ parentContainer?: interfaces.Container;
22
+ playgroundContainer?: interfaces.Container;
23
+ playgroundContext?: any;
24
+ autoFocus?: boolean;
25
+ autoResize?: boolean;
26
+ zoomEnable?: boolean;
27
+ plugins?: PluginsProvider<any>;
28
+ customPluginContext?: (container: interfaces.Container) => PluginContext;
29
+ }
30
+
31
+ /**
32
+ * Playground Vue 容器:创建 inversify 容器并 provide 给子组件
33
+ */
34
+ export const PlaygroundVueProvider = defineComponent({
35
+ name: 'PlaygroundVueProvider',
36
+ props: {
37
+ containerModules: Array as PropType<interfaces.ContainerModule[]>,
38
+ parentContainer: Object as PropType<interfaces.Container>,
39
+ playgroundContainer: Object as PropType<interfaces.Container>,
40
+ playgroundContext: { type: null as unknown as PropType<any>, default: undefined },
41
+ autoFocus: { type: Boolean, default: true },
42
+ autoResize: { type: Boolean, default: true },
43
+ zoomEnable: { type: Boolean, default: true },
44
+ plugins: Function as PropType<PluginsProvider<any>>,
45
+ customPluginContext: Function as PropType<(container: interfaces.Container) => PluginContext>,
46
+ },
47
+ setup(props, { slots, expose }) {
48
+ const container = (() => {
49
+ let flowContainer: interfaces.Container;
50
+ if (props.playgroundContainer) {
51
+ flowContainer = props.playgroundContainer;
52
+ } else {
53
+ flowContainer = createPlaygroundContainer(
54
+ {
55
+ autoFocus: props.autoFocus,
56
+ autoResize: props.autoResize,
57
+ zoomEnable: props.zoomEnable,
58
+ },
59
+ props.parentContainer
60
+ );
61
+ if (props.playgroundContext) {
62
+ flowContainer.rebind(PlaygroundContext).toConstantValue(props.playgroundContext);
63
+ }
64
+ if (props.containerModules) {
65
+ props.containerModules.forEach((module) => flowContainer.load(module));
66
+ }
67
+ }
68
+ return flowContainer;
69
+ })();
70
+
71
+ const playground = (() => {
72
+ const instance = container.get(Playground);
73
+ let ctx: PluginContext;
74
+ if (props.customPluginContext) {
75
+ ctx = props.customPluginContext(container);
76
+ container.rebind(PluginContext).toConstantValue(ctx);
77
+ } else {
78
+ ctx = container.get<PluginContext>(PluginContext);
79
+ }
80
+ if (props.plugins) {
81
+ loadPlugins(props.plugins(ctx), container);
82
+ }
83
+ instance.init();
84
+ return instance;
85
+ })();
86
+
87
+ provide(PlaygroundVueContainerKey, container);
88
+ provide(PlaygroundVueRefKey, playground);
89
+ provide(PlaygroundVueContextKey, props.playgroundContext);
90
+
91
+ const pluginContext = container.get<PluginContext>(PluginContext);
92
+ expose(pluginContext);
93
+
94
+ let effectSignal = 0;
95
+ onMounted(() => {
96
+ effectSignal += 1;
97
+ });
98
+ onBeforeUnmount(() => {
99
+ // 开发环境下延迟处理 dispose,防止 HMR / Strict 双调用卸载
100
+ if (process.env.NODE_ENV === 'development') {
101
+ const FRAME = 16;
102
+ setTimeout(() => {
103
+ effectSignal -= 1;
104
+ if (effectSignal === 0) {
105
+ playground.dispose();
106
+ }
107
+ }, FRAME);
108
+ return;
109
+ }
110
+ playground.dispose();
111
+ });
112
+
113
+ return () => slots.default?.();
114
+ },
115
+ });
@@ -0,0 +1,44 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { onMounted, ref, type CSSProperties } from 'vue';
7
+
8
+ import { usePlayground } from '../composables/use-playground';
9
+ import { useService } from '../composables/use-service';
10
+ import { PlaygroundConfig } from '../playground-config';
11
+
12
+ defineOptions({ name: 'PlaygroundVueRenderer' });
13
+
14
+ const props = defineProps<{
15
+ className?: string;
16
+ style?: CSSProperties;
17
+ }>();
18
+
19
+ const playground = usePlayground();
20
+ const playgroundConfig = useService<PlaygroundConfig>(PlaygroundConfig);
21
+ const containerRef = ref<HTMLElement>();
22
+
23
+ onMounted(() => {
24
+ if (!containerRef.value) {
25
+ return;
26
+ }
27
+ playground.setParent(containerRef.value);
28
+ playground.ready();
29
+ if (playgroundConfig.autoFocus) {
30
+ playground.node.focus();
31
+ }
32
+ });
33
+ </script>
34
+
35
+ <template>
36
+ <div
37
+ ref="containerRef"
38
+ :class="['gedit-playground-container', props.className]"
39
+ :style="props.style"
40
+ />
41
+ <Teleport v-if="$slots.default" :to="playground.node">
42
+ <slot />
43
+ </Teleport>
44
+ </template>