@formicoidea/labre-core 0.37.0 → 0.38.2

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 (54) hide show
  1. package/dist/_pkgs/affine-block-frame/frame-manager.d.ts +31 -0
  2. package/dist/_pkgs/affine-block-frame/frame-manager.js +62 -2
  3. package/dist/_pkgs/affine-block-frame/frame-tool.js +6 -2
  4. package/dist/_pkgs/affine-block-surface/extensions/audit.js +12 -34
  5. package/dist/_pkgs/affine-block-surface/extensions/reading-toolbar.js +12 -12
  6. package/dist/_pkgs/affine-block-surface/extensions/reading.js +10 -28
  7. package/dist/_pkgs/affine-block-surface/extensions/validation.d.ts +321 -16
  8. package/dist/_pkgs/affine-block-surface/extensions/validation.js +945 -62
  9. package/dist/_pkgs/affine-block-surface/framework-background/facts.d.ts +24 -0
  10. package/dist/_pkgs/affine-block-surface/framework-background/facts.js +31 -0
  11. package/dist/_pkgs/affine-block-surface/framework-background/index.d.ts +1 -0
  12. package/dist/_pkgs/affine-block-surface/framework-background/index.js +1 -0
  13. package/dist/_pkgs/affine-block-surface/framework-background/stacking.d.ts +131 -0
  14. package/dist/_pkgs/affine-block-surface/framework-background/stacking.js +184 -0
  15. package/dist/_pkgs/affine-block-surface/utils/sort.d.ts +15 -1
  16. package/dist/_pkgs/affine-block-surface/utils/sort.js +30 -31
  17. package/dist/_pkgs/affine-block-surface/view.js +5 -0
  18. package/dist/_pkgs/affine-components/highlight-dropdown-menu/highlight-duotone-icon.js +8 -8
  19. package/dist/_pkgs/affine-components/highlight-dropdown-menu/text-duotone-icon.js +11 -11
  20. package/dist/_pkgs/affine-components/icons/text.js +426 -426
  21. package/dist/_pkgs/affine-gfx-group/element-renderer/utils.js +3 -1
  22. package/dist/_pkgs/affine-gfx-template/index.d.ts +1 -0
  23. package/dist/_pkgs/affine-gfx-template/index.js +1 -0
  24. package/dist/_pkgs/affine-gfx-template/make-snapshot.d.ts +16 -2
  25. package/dist/_pkgs/affine-gfx-template/make-snapshot.js +43 -4
  26. package/dist/_pkgs/affine-gfx-template/services/template-middlewares.js +1 -0
  27. package/dist/_pkgs/affine-gfx-template/services/template.d.ts +6 -0
  28. package/dist/_pkgs/affine-gfx-template/services/template.js +6 -0
  29. package/dist/_pkgs/affine-gfx-template/snapshot-from-action.d.ts +20 -0
  30. package/dist/_pkgs/affine-gfx-template/snapshot-from-action.js +205 -0
  31. package/dist/_pkgs/affine-gfx-template/toolbar/template-panel.js +4 -0
  32. package/dist/_pkgs/affine-gfx-template/toolbar/template-type.d.ts +13 -0
  33. package/dist/_pkgs/affine-inline-link/link-node/configs/toolbar.d.ts +11 -17
  34. package/dist/_pkgs/affine-inline-link/link-node/configs/toolbar.js +55 -14
  35. package/dist/_pkgs/affine-model/elements/cynefin/cynefin.d.ts +9 -20
  36. package/dist/_pkgs/affine-model/elements/cynefin/cynefin.js +7 -28
  37. package/dist/_pkgs/affine-model/elements/edgy/board.d.ts +9 -21
  38. package/dist/_pkgs/affine-model/elements/edgy/board.js +8 -29
  39. package/dist/_pkgs/affine-model/elements/edgy/facets.d.ts +14 -28
  40. package/dist/_pkgs/affine-model/elements/edgy/facets.js +12 -36
  41. package/dist/_pkgs/affine-model/elements/estuarine/estuarine.d.ts +9 -19
  42. package/dist/_pkgs/affine-model/elements/estuarine/estuarine.js +7 -27
  43. package/dist/_pkgs/affine-shared/services/link-preview-service/link-preview-service.d.ts +28 -0
  44. package/dist/_pkgs/affine-shared/services/link-preview-service/link-preview-service.js +20 -3
  45. package/dist/_pkgs/affine-widget-edgeless-auto-connect/index.js +124 -124
  46. package/dist/_pkgs/affine-widget-edgeless-zoom-toolbar/index.js +26 -26
  47. package/dist/_pkgs/affine-widget-keyboard-toolbar/icons.js +98 -98
  48. package/dist/_pkgs/affine-widget-page-dragging-area/index.js +10 -10
  49. package/dist/_pkgs/affine-widget-viewport-overlay/index.js +13 -13
  50. package/dist/_pkgs/data-view/core/group-by/renderer/boolean-group.js +11 -11
  51. package/dist/_pkgs/data-view/core/utils/menu-title.js +17 -17
  52. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/top/group-title.js +18 -18
  53. package/dist/_pkgs/std/gfx/model/surface/surface-model.js +12 -2
  54. package/package.json +1 -1
@@ -32,9 +32,8 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
32
32
  }
33
33
  return useValue ? value : void 0;
34
34
  };
35
- import { Bound, getPointsFromBoundWithRotation, linePolygonIntersects, polygonNearestPoint, } from '../../../global/gfx/index.js';
36
- import { field, GfxPrimitiveElementModel } from '../../../std/gfx/index.js';
37
- import { backgroundIncludesPoint } from '../framework-background/index.js';
35
+ import { field } from '../../../std/gfx/index.js';
36
+ import { FrameworkBackgroundElementModel } from '../framework-background/index.js';
38
37
  /**
39
38
  * A static "Liminal Cynefin" framework diagram: the hand-drawn five-domain
40
39
  * boundary (Complex / Complicated / Chaotic / Clear + central Confusion), the
@@ -42,11 +41,13 @@ import { backgroundIncludesPoint } from '../framework-background/index.js';
42
41
  * boundary — reproduced from the official SVG paths. The user places regular
43
42
  * edgeless elements on top of it.
44
43
  *
45
- * Mirrors the Wardley / EDGY backgrounds: extends {@link GfxPrimitiveElementModel}
46
- * so it inherits selection, move, copy/paste, duplicate, align and undo/redo.
44
+ * An INSTANCE of the framework-background primitive
45
+ * ({@link FrameworkBackgroundElementModel}), like the Wardley / EDGY
46
+ * backgrounds: the passive-canvas geometry comes from the primitive, the
47
+ * fields below are the persisted document.
47
48
  */
48
49
  let CynefinElementModel = (() => {
49
- let _classSuper = GfxPrimitiveElementModel;
50
+ let _classSuper = FrameworkBackgroundElementModel;
50
51
  let _resizeEnabled_decorators;
51
52
  let _resizeEnabled_initializers = [];
52
53
  let _resizeEnabled_extraInitializers = [];
@@ -85,28 +86,6 @@ let CynefinElementModel = (() => {
85
86
  get type() {
86
87
  return 'cynefin';
87
88
  }
88
- get connectable() {
89
- return false;
90
- }
91
- containsBound(bounds) {
92
- const points = getPointsFromBoundWithRotation(this);
93
- return points.some(point => bounds.containsPoint(point));
94
- }
95
- getLineIntersections(start, end) {
96
- const points = getPointsFromBoundWithRotation(this);
97
- return linePolygonIntersects(start, end, points);
98
- }
99
- getNearestPoint(point) {
100
- return polygonNearestPoint(Bound.deserialize(this.xywh).points, point);
101
- }
102
- /**
103
- * Picked by its BORDER band — see {@link backgroundIncludesPoint}. The five
104
- * domains are a picture the user drops elements onto, so the clicks inside
105
- * the frame belong to those elements.
106
- */
107
- includesPoint(x, y, options) {
108
- return backgroundIncludesPoint(this, x, y, options);
109
- }
110
89
  #resizeEnabled_accessor_storage = __runInitializers(this, _resizeEnabled_initializers, true);
111
90
  get resizeEnabled() { return this.#resizeEnabled_accessor_storage; }
112
91
  set resizeEnabled(value) { this.#resizeEnabled_accessor_storage = value; }
@@ -1,11 +1,7 @@
1
- import type { IVec } from '../../../global/gfx/index.js';
2
- import { Bound } from '../../../global/gfx/index.js';
3
1
  import type { SerializedXYWH } from '../../../global/gfx/index.js';
4
- import type { BaseElementProps, PointTestOptions } from '../../../std/gfx/index.js';
5
- import { GfxPrimitiveElementModel } from '../../../std/gfx/index.js';
6
- export type EdgyBoardProps = BaseElementProps & {
7
- /** When false the resize handles are hidden — toggled from the toolbar. */
8
- resizeEnabled?: boolean;
2
+ import { FrameworkBackgroundElementModel } from '../framework-background/index.js';
3
+ import type { FrameworkBackgroundProps } from '../framework-background/index.js';
4
+ export type EdgyBoardProps = FrameworkBackgroundProps & {
9
5
  /** When false the board stops granting the hover spotlight. */
10
6
  spotlightEnabled?: boolean;
11
7
  };
@@ -14,22 +10,14 @@ export type EdgyBoardProps = BaseElementProps & {
14
10
  * shapes and connectors on top of it and the board grants them the dependency
15
11
  * spotlight-on-hover behavior (see the surface `Spotlight` extension).
16
12
  *
17
- * Mirrors {@link EdgyFacetsElementModel}: a passive canvas that inherits
18
- * selection, move, copy/paste, duplicate, align and undo/redo for free.
13
+ * An INSTANCE of the framework-background primitive
14
+ * ({@link FrameworkBackgroundElementModel}): the passive-canvas geometry —
15
+ * non-connectable, picked by its border band, lassoed and intersected as a
16
+ * rotated rectangle — comes from the primitive, and the fields below are the
17
+ * persisted document, unchanged.
19
18
  */
20
- export declare class EdgyBoardElementModel extends GfxPrimitiveElementModel<EdgyBoardProps> {
19
+ export declare class EdgyBoardElementModel extends FrameworkBackgroundElementModel<EdgyBoardProps> {
21
20
  get type(): string;
22
- /** Connectors must link elements, never the board itself. */
23
- get connectable(): boolean;
24
- containsBound(bounds: Bound): boolean;
25
- getLineIntersections(start: IVec, end: IVec): import("../../../global/gfx/index.js").PointLocation[] | null;
26
- getNearestPoint(point: IVec): IVec;
27
- /**
28
- * Picked by its BORDER band: a board is a passive canvas and the clicks over
29
- * its area belong to what the user laid on it. Same test every framework
30
- * background runs — see {@link backgroundIncludesPoint}.
31
- */
32
- includesPoint(x: number, y: number, options?: PointTestOptions): boolean;
33
21
  accessor resizeEnabled: boolean;
34
22
  accessor spotlightEnabled: boolean;
35
23
  accessor rotate: number;
@@ -32,19 +32,21 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
32
32
  }
33
33
  return useValue ? value : void 0;
34
34
  };
35
- import { Bound, getPointsFromBoundWithRotation, linePolygonIntersects, polygonNearestPoint, } from '../../../global/gfx/index.js';
36
- import { field, GfxPrimitiveElementModel } from '../../../std/gfx/index.js';
37
- import { backgroundIncludesPoint } from '../framework-background/index.js';
35
+ import { field } from '../../../std/gfx/index.js';
36
+ import { FrameworkBackgroundElementModel } from '../framework-background/index.js';
38
37
  /**
39
38
  * A blank white board for free-form EDGY modelling: the user places EDGY base
40
39
  * shapes and connectors on top of it and the board grants them the dependency
41
40
  * spotlight-on-hover behavior (see the surface `Spotlight` extension).
42
41
  *
43
- * Mirrors {@link EdgyFacetsElementModel}: a passive canvas that inherits
44
- * selection, move, copy/paste, duplicate, align and undo/redo for free.
42
+ * An INSTANCE of the framework-background primitive
43
+ * ({@link FrameworkBackgroundElementModel}): the passive-canvas geometry —
44
+ * non-connectable, picked by its border band, lassoed and intersected as a
45
+ * rotated rectangle — comes from the primitive, and the fields below are the
46
+ * persisted document, unchanged.
45
47
  */
46
48
  let EdgyBoardElementModel = (() => {
47
- let _classSuper = GfxPrimitiveElementModel;
49
+ let _classSuper = FrameworkBackgroundElementModel;
48
50
  let _resizeEnabled_decorators;
49
51
  let _resizeEnabled_initializers = [];
50
52
  let _resizeEnabled_extraInitializers = [];
@@ -73,29 +75,6 @@ let EdgyBoardElementModel = (() => {
73
75
  get type() {
74
76
  return 'edgyBoard';
75
77
  }
76
- /** Connectors must link elements, never the board itself. */
77
- get connectable() {
78
- return false;
79
- }
80
- containsBound(bounds) {
81
- const points = getPointsFromBoundWithRotation(this);
82
- return points.some(point => bounds.containsPoint(point));
83
- }
84
- getLineIntersections(start, end) {
85
- const points = getPointsFromBoundWithRotation(this);
86
- return linePolygonIntersects(start, end, points);
87
- }
88
- getNearestPoint(point) {
89
- return polygonNearestPoint(Bound.deserialize(this.xywh).points, point);
90
- }
91
- /**
92
- * Picked by its BORDER band: a board is a passive canvas and the clicks over
93
- * its area belong to what the user laid on it. Same test every framework
94
- * background runs — see {@link backgroundIncludesPoint}.
95
- */
96
- includesPoint(x, y, options) {
97
- return backgroundIncludesPoint(this, x, y, options);
98
- }
99
78
  #resizeEnabled_accessor_storage = __runInitializers(this, _resizeEnabled_initializers, true);
100
79
  get resizeEnabled() { return this.#resizeEnabled_accessor_storage; }
101
80
  set resizeEnabled(value) { this.#resizeEnabled_accessor_storage = value; }
@@ -1,10 +1,7 @@
1
- import type { IVec, SerializedXYWH } from '../../../global/gfx/index.js';
2
- import { Bound } from '../../../global/gfx/index.js';
3
- import type { BaseElementProps, PointTestOptions } from '../../../std/gfx/index.js';
4
- import { GfxPrimitiveElementModel } from '../../../std/gfx/index.js';
5
- export type EdgyFacetsProps = BaseElementProps & {
6
- /** When false the resize handles are hidden — toggled from the toolbar. */
7
- resizeEnabled?: boolean;
1
+ import type { SerializedXYWH } from '../../../global/gfx/index.js';
2
+ import { FrameworkBackgroundElementModel } from '../framework-background/index.js';
3
+ import type { FrameworkBackgroundProps } from '../framework-background/index.js';
4
+ export type EdgyFacetsProps = FrameworkBackgroundProps & {
8
5
  /** When false the three facet name labels are hidden. */
9
6
  showLabels?: boolean;
10
7
  /** When false the six white zone pictograms are hidden. */
@@ -35,29 +32,18 @@ export type EdgyFacetsProps = BaseElementProps & {
35
32
  * white pictograms, drawn on the surface canvas. The user places regular
36
33
  * edgeless elements (the EDGY base shapes) on top of it.
37
34
  *
38
- * Mirrors {@link WardleyBackgroundElementModel}: extends
39
- * {@link GfxPrimitiveElementModel} so it inherits selection, move, copy/paste,
40
- * duplicate, align and undo/redo for free.
35
+ * An INSTANCE of the framework-background primitive
36
+ * ({@link FrameworkBackgroundElementModel}), like the Wardley background: the
37
+ * passive-canvas geometry comes from the primitive, the fields below are the
38
+ * persisted document.
39
+ *
40
+ * The facet LABELS stay double-clickable all the same: their zones are added
41
+ * by `EdgyView.includesPoint`, which is what the pointer router consults, so
42
+ * the rename target lives with the code that draws it and the model layer
43
+ * stays free of it.
41
44
  */
42
- export declare class EdgyFacetsElementModel extends GfxPrimitiveElementModel<EdgyFacetsProps> {
45
+ export declare class EdgyFacetsElementModel extends FrameworkBackgroundElementModel<EdgyFacetsProps> {
43
46
  get type(): string;
44
- /**
45
- * The diagram is a passive canvas: connectors must not snap their endpoints
46
- * to it (an EDGY link should connect elements, never the facets diagram).
47
- */
48
- get connectable(): boolean;
49
- containsBound(bounds: Bound): boolean;
50
- getLineIntersections(start: IVec, end: IVec): import("../../../global/gfx/index.js").PointLocation[] | null;
51
- getNearestPoint(point: IVec): IVec;
52
- /**
53
- * Picked by its BORDER band — see {@link backgroundIncludesPoint}.
54
- *
55
- * The facet LABELS stay double-clickable all the same: their zones are added
56
- * by `EdgyView.includesPoint`, which is what the pointer router consults, so
57
- * the rename target lives with the code that draws it and the model layer
58
- * stays free of it.
59
- */
60
- includesPoint(x: number, y: number, options?: PointTestOptions): boolean;
61
47
  accessor resizeEnabled: boolean;
62
48
  accessor showLabels: boolean;
63
49
  accessor showPictos: boolean;
@@ -32,9 +32,8 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
32
32
  }
33
33
  return useValue ? value : void 0;
34
34
  };
35
- import { Bound, getPointsFromBoundWithRotation, linePolygonIntersects, polygonNearestPoint, } from '../../../global/gfx/index.js';
36
- import { field, GfxPrimitiveElementModel } from '../../../std/gfx/index.js';
37
- import { backgroundIncludesPoint } from '../framework-background/index.js';
35
+ import { field } from '../../../std/gfx/index.js';
36
+ import { FrameworkBackgroundElementModel } from '../framework-background/index.js';
38
37
  /**
39
38
  * A static "EDGY Enterprise Design Facets" diagram: three overlapping circles
40
39
  * (Identity / Architecture / Experience) with their three pairwise
@@ -42,12 +41,18 @@ import { backgroundIncludesPoint } from '../framework-background/index.js';
42
41
  * white pictograms, drawn on the surface canvas. The user places regular
43
42
  * edgeless elements (the EDGY base shapes) on top of it.
44
43
  *
45
- * Mirrors {@link WardleyBackgroundElementModel}: extends
46
- * {@link GfxPrimitiveElementModel} so it inherits selection, move, copy/paste,
47
- * duplicate, align and undo/redo for free.
44
+ * An INSTANCE of the framework-background primitive
45
+ * ({@link FrameworkBackgroundElementModel}), like the Wardley background: the
46
+ * passive-canvas geometry comes from the primitive, the fields below are the
47
+ * persisted document.
48
+ *
49
+ * The facet LABELS stay double-clickable all the same: their zones are added
50
+ * by `EdgyView.includesPoint`, which is what the pointer router consults, so
51
+ * the rename target lives with the code that draws it and the model layer
52
+ * stays free of it.
48
53
  */
49
54
  let EdgyFacetsElementModel = (() => {
50
- let _classSuper = GfxPrimitiveElementModel;
55
+ let _classSuper = FrameworkBackgroundElementModel;
51
56
  let _resizeEnabled_decorators;
52
57
  let _resizeEnabled_initializers = [];
53
58
  let _resizeEnabled_extraInitializers = [];
@@ -106,35 +111,6 @@ let EdgyFacetsElementModel = (() => {
106
111
  get type() {
107
112
  return 'edgy';
108
113
  }
109
- /**
110
- * The diagram is a passive canvas: connectors must not snap their endpoints
111
- * to it (an EDGY link should connect elements, never the facets diagram).
112
- */
113
- get connectable() {
114
- return false;
115
- }
116
- containsBound(bounds) {
117
- const points = getPointsFromBoundWithRotation(this);
118
- return points.some(point => bounds.containsPoint(point));
119
- }
120
- getLineIntersections(start, end) {
121
- const points = getPointsFromBoundWithRotation(this);
122
- return linePolygonIntersects(start, end, points);
123
- }
124
- getNearestPoint(point) {
125
- return polygonNearestPoint(Bound.deserialize(this.xywh).points, point);
126
- }
127
- /**
128
- * Picked by its BORDER band — see {@link backgroundIncludesPoint}.
129
- *
130
- * The facet LABELS stay double-clickable all the same: their zones are added
131
- * by `EdgyView.includesPoint`, which is what the pointer router consults, so
132
- * the rename target lives with the code that draws it and the model layer
133
- * stays free of it.
134
- */
135
- includesPoint(x, y, options) {
136
- return backgroundIncludesPoint(this, x, y, options);
137
- }
138
114
  #resizeEnabled_accessor_storage = __runInitializers(this, _resizeEnabled_initializers, true);
139
115
  get resizeEnabled() { return this.#resizeEnabled_accessor_storage; }
140
116
  set resizeEnabled(value) { this.#resizeEnabled_accessor_storage = value; }
@@ -1,10 +1,7 @@
1
- import type { IVec, SerializedXYWH } from '../../../global/gfx/index.js';
2
- import { Bound } from '../../../global/gfx/index.js';
3
- import type { BaseElementProps, PointTestOptions } from '../../../std/gfx/index.js';
4
- import { GfxPrimitiveElementModel } from '../../../std/gfx/index.js';
5
- export type EstuarineProps = BaseElementProps & {
6
- /** When false the resize handles are hidden — toggled from the toolbar. */
7
- resizeEnabled?: boolean;
1
+ import type { SerializedXYWH } from '../../../global/gfx/index.js';
2
+ import { FrameworkBackgroundElementModel } from '../framework-background/index.js';
3
+ import type { FrameworkBackgroundProps } from '../framework-background/index.js';
4
+ export type EstuarineProps = FrameworkBackgroundProps & {
8
5
  /** Per-curve visibility (the curve + its legend) — toggled from the toolbar. */
9
6
  showLiminal?: boolean;
10
7
  showVolatile?: boolean;
@@ -18,20 +15,13 @@ export type EstuarineProps = BaseElementProps & {
18
15
  * Volatile (red, dipping below zero) and Counter-factual (dark) — each with its
19
16
  * legend. The user drops hexagon constraint nodes (native shapes) into the space.
20
17
  *
21
- * Mirrors the Wardley / EDGY backgrounds.
18
+ * An INSTANCE of the framework-background primitive
19
+ * ({@link FrameworkBackgroundElementModel}), like the Wardley / EDGY
20
+ * backgrounds: the passive-canvas geometry comes from the primitive, the
21
+ * fields below are the persisted document.
22
22
  */
23
- export declare class EstuarineElementModel extends GfxPrimitiveElementModel<EstuarineProps> {
23
+ export declare class EstuarineElementModel extends FrameworkBackgroundElementModel<EstuarineProps> {
24
24
  get type(): string;
25
- get connectable(): boolean;
26
- containsBound(bounds: Bound): boolean;
27
- getLineIntersections(start: IVec, end: IVec): import("../../../global/gfx/index.js").PointLocation[] | null;
28
- getNearestPoint(point: IVec): IVec;
29
- /**
30
- * Picked by its BORDER band — see {@link backgroundIncludesPoint}. The map is
31
- * a space constraint nodes are dropped into, so the clicks inside it are
32
- * theirs.
33
- */
34
- includesPoint(x: number, y: number, options?: PointTestOptions): boolean;
35
25
  accessor resizeEnabled: boolean;
36
26
  accessor showLiminal: boolean;
37
27
  accessor showVolatile: boolean;
@@ -32,19 +32,21 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
32
32
  }
33
33
  return useValue ? value : void 0;
34
34
  };
35
- import { Bound, getPointsFromBoundWithRotation, linePolygonIntersects, polygonNearestPoint, } from '../../../global/gfx/index.js';
36
- import { field, GfxPrimitiveElementModel } from '../../../std/gfx/index.js';
37
- import { backgroundIncludesPoint } from '../framework-background/index.js';
35
+ import { field } from '../../../std/gfx/index.js';
36
+ import { FrameworkBackgroundElementModel } from '../framework-background/index.js';
38
37
  /**
39
38
  * A static "Estuarine framework" map: the 2D energy (e, vertical, double-headed)
40
39
  * / time (t, horizontal) space with the three reference curves — Liminal (green),
41
40
  * Volatile (red, dipping below zero) and Counter-factual (dark) — each with its
42
41
  * legend. The user drops hexagon constraint nodes (native shapes) into the space.
43
42
  *
44
- * Mirrors the Wardley / EDGY backgrounds.
43
+ * An INSTANCE of the framework-background primitive
44
+ * ({@link FrameworkBackgroundElementModel}), like the Wardley / EDGY
45
+ * backgrounds: the passive-canvas geometry comes from the primitive, the
46
+ * fields below are the persisted document.
45
47
  */
46
48
  let EstuarineElementModel = (() => {
47
- let _classSuper = GfxPrimitiveElementModel;
49
+ let _classSuper = FrameworkBackgroundElementModel;
48
50
  let _resizeEnabled_decorators;
49
51
  let _resizeEnabled_initializers = [];
50
52
  let _resizeEnabled_extraInitializers = [];
@@ -88,28 +90,6 @@ let EstuarineElementModel = (() => {
88
90
  get type() {
89
91
  return 'estuarine';
90
92
  }
91
- get connectable() {
92
- return false;
93
- }
94
- containsBound(bounds) {
95
- const points = getPointsFromBoundWithRotation(this);
96
- return points.some(point => bounds.containsPoint(point));
97
- }
98
- getLineIntersections(start, end) {
99
- const points = getPointsFromBoundWithRotation(this);
100
- return linePolygonIntersects(start, end, points);
101
- }
102
- getNearestPoint(point) {
103
- return polygonNearestPoint(Bound.deserialize(this.xywh).points, point);
104
- }
105
- /**
106
- * Picked by its BORDER band — see {@link backgroundIncludesPoint}. The map is
107
- * a space constraint nodes are dropped into, so the clicks inside it are
108
- * theirs.
109
- */
110
- includesPoint(x, y, options) {
111
- return backgroundIncludesPoint(this, x, y, options);
112
- }
113
93
  #resizeEnabled_accessor_storage = __runInitializers(this, _resizeEnabled_initializers, true);
114
94
  get resizeEnabled() { return this.#resizeEnabled_accessor_storage; }
115
95
  set resizeEnabled(value) { this.#resizeEnabled_accessor_storage = value; }
@@ -14,6 +14,10 @@ export type LinkPreviewResponseData = {
14
14
  videos?: string[];
15
15
  favicons?: string[];
16
16
  };
17
+ /**
18
+ * Returns extra headers to send with a link preview request.
19
+ */
20
+ export type LinkPreviewHeadersFn = () => Record<string, string> | Promise<Record<string, string>>;
17
21
  export interface LinkPreviewProvider {
18
22
  /**
19
23
  * Query link preview data for a given URL
@@ -27,15 +31,39 @@ export interface LinkPreviewProvider {
27
31
  * Get the endpoint for link preview
28
32
  */
29
33
  endpoint: string;
34
+ /**
35
+ * Set a hook returning extra headers, merged over `Content-Type` on every
36
+ * request sent to the configured endpoint (e.g. an `Authorization` header).
37
+ * Pass `null` to remove it.
38
+ *
39
+ * Optional: hosts implementing this provider themselves may omit it.
40
+ */
41
+ setHeaders?: (fn: LinkPreviewHeadersFn | null) => void;
42
+ /**
43
+ * Set the endpoint used for X/Twitter status URLs.
44
+ *
45
+ * The value is a **prefix**: the tweet id is appended to it, so
46
+ * `https://example.com/tweet/` is fetched as
47
+ * `https://example.com/tweet/1234567890`. Pass `null` to disable the special
48
+ * path entirely, sending tweet URLs through the standard endpoint instead.
49
+ *
50
+ * Optional: hosts implementing this provider themselves may omit it.
51
+ */
52
+ setTwitterEndpoint?: (endpoint: string | null) => void;
30
53
  }
31
54
  export declare const LinkPreviewServiceIdentifier: import("../../../global/di/types.js").ServiceIdentifier<LinkPreviewProvider> & (<U extends LinkPreviewProvider = LinkPreviewProvider>(variant: import("../../../global/di/types.js").ServiceVariant) => import("../../../global/di/types.js").ServiceIdentifier<U>);
32
55
  export declare class LinkPreviewService extends Extension implements LinkPreviewProvider {
33
56
  private readonly _cache;
34
57
  static setup(di: Container): void;
35
58
  private _endpoint;
59
+ private _headers;
60
+ private _twitterEndpoint;
36
61
  constructor(_cache: LinkPreviewCacheProvider);
37
62
  get endpoint(): string;
38
63
  setEndpoint: (endpoint: string) => void;
64
+ setHeaders: (fn: LinkPreviewHeadersFn | null) => void;
65
+ setTwitterEndpoint: (endpoint: string | null) => void;
66
+ private readonly _resolveHeaders;
39
67
  private readonly _fetchTwitterPreview;
40
68
  private readonly _fetchStandardPreview;
41
69
  private readonly _isTwitterUrl;
@@ -5,6 +5,8 @@ import { Extension } from '../../../store/index.js';
5
5
  import { DEFAULT_LINK_PREVIEW_ENDPOINT } from '../../consts/index.js';
6
6
  import { isAbortError } from '../../utils/is-abort-error.js';
7
7
  import { LinkPreviewCacheIdentifier, } from './link-preview-cache.js';
8
+ /** Third-party endpoint used for X/Twitter status URLs by default. */
9
+ const DEFAULT_TWITTER_PREVIEW_ENDPOINT = 'https://api.fxtwitter.com/status/';
8
10
  export const LinkPreviewServiceIdentifier = createIdentifier('AffineLinkPreviewService');
9
11
  export class LinkPreviewService extends Extension {
10
12
  static setup(di) {
@@ -16,17 +18,31 @@ export class LinkPreviewService extends Extension {
16
18
  super();
17
19
  this._cache = _cache;
18
20
  this._endpoint = DEFAULT_LINK_PREVIEW_ENDPOINT;
21
+ this._headers = null;
22
+ this._twitterEndpoint = DEFAULT_TWITTER_PREVIEW_ENDPOINT;
19
23
  this.setEndpoint = (endpoint) => {
20
24
  this._endpoint = endpoint;
21
25
  };
26
+ this.setHeaders = (fn) => {
27
+ this._headers = fn;
28
+ };
29
+ this.setTwitterEndpoint = (endpoint) => {
30
+ this._twitterEndpoint = endpoint;
31
+ };
32
+ this._resolveHeaders = async () => (this._headers ? await this._headers() : {});
22
33
  this._fetchTwitterPreview = async (url, signal) => {
23
34
  try {
24
35
  const match = /\/status\/(\d+)/.exec(url);
25
36
  if (!match) {
26
37
  throw new BlockSuiteError(ErrorCode.DefaultRuntimeError, `Invalid tweet URL: ${url}`);
27
38
  }
28
- const apiUrl = `https://api.fxtwitter.com/status/${match[1]}`;
29
- const response = await fetch(apiUrl, { signal }).then(res => res.json());
39
+ const endpoint = this._twitterEndpoint ?? DEFAULT_TWITTER_PREVIEW_ENDPOINT;
40
+ const apiUrl = `${endpoint}${match[1]}`;
41
+ // Never leak the host headers (a JWT, typically) to the default third-party endpoint.
42
+ const headers = endpoint === DEFAULT_TWITTER_PREVIEW_ENDPOINT
43
+ ? undefined
44
+ : await this._resolveHeaders();
45
+ const response = await fetch(apiUrl, { headers, signal }).then(res => res.json());
30
46
  const tweet = response?.tweet;
31
47
  if (!tweet) {
32
48
  throw new BlockSuiteError(ErrorCode.DefaultRuntimeError, `Invalid tweet response: ${url}`);
@@ -49,6 +65,7 @@ export class LinkPreviewService extends Extension {
49
65
  method: 'POST',
50
66
  headers: {
51
67
  'Content-Type': 'application/json',
68
+ ...(await this._resolveHeaders()),
52
69
  },
53
70
  body: JSON.stringify({ url }),
54
71
  signal,
@@ -87,7 +104,7 @@ export class LinkPreviewService extends Extension {
87
104
  url.includes('/status/'));
88
105
  };
89
106
  this._fetchPreview = async (url, signal) => {
90
- if (this._isTwitterUrl(url)) {
107
+ if (this._twitterEndpoint !== null && this._isTwitterUrl(url)) {
91
108
  return this._fetchTwitterPreview(url, signal);
92
109
  }
93
110
  return this._fetchStandardPreview(url, signal);