@formicoidea/labre-ddd-shared 0.58.0 → 0.60.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/headless.d.ts +14 -0
- package/dist/headless.js +14 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/shared/consts.d.ts +7 -1
- package/dist/shared/consts.js +8 -2
- package/dist/shared/elements.d.ts +109 -0
- package/dist/shared/elements.js +240 -0
- package/dist/shared/prefabs.d.ts +13 -41
- package/dist/shared/prefabs.js +50 -158
- package/dist/shared/utils.d.ts +0 -1
- package/dist/shared/utils.js +0 -1
- package/package.json +6 -2
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@labre/affine-gfx-ddd-shared/headless` — the DDD tables and the pure
|
|
3
|
+
* element builders, with no editor behind them (`docs/adr/0045`): what a
|
|
4
|
+
* board's `./interchange` toolbox builds a sticky, a bubble, a dot, a marker,
|
|
5
|
+
* a cloud or a relationship from. The package index re-exports every one of
|
|
6
|
+
* these unchanged.
|
|
7
|
+
*
|
|
8
|
+
* Held by `interchange-headless.unit.spec.ts` in `packages/affine/all`: add
|
|
9
|
+
* only from files that import nothing but the headless entries of core
|
|
10
|
+
* (`@labre/global`, `@labre/affine-model/headless`,
|
|
11
|
+
* `@labre/affine-shared/headless`, `@labre/affine-block-surface/interchange`).
|
|
12
|
+
*/
|
|
13
|
+
export * from './shared/consts.js';
|
|
14
|
+
export * from './shared/elements.js';
|
package/dist/headless.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@labre/affine-gfx-ddd-shared/headless` — the DDD tables and the pure
|
|
3
|
+
* element builders, with no editor behind them (`docs/adr/0045`): what a
|
|
4
|
+
* board's `./interchange` toolbox builds a sticky, a bubble, a dot, a marker,
|
|
5
|
+
* a cloud or a relationship from. The package index re-exports every one of
|
|
6
|
+
* these unchanged.
|
|
7
|
+
*
|
|
8
|
+
* Held by `interchange-headless.unit.spec.ts` in `packages/affine/all`: add
|
|
9
|
+
* only from files that import nothing but the headless entries of core
|
|
10
|
+
* (`@labre/global`, `@labre/affine-model/headless`,
|
|
11
|
+
* `@labre/affine-shared/headless`, `@labre/affine-block-surface/interchange`).
|
|
12
|
+
*/
|
|
13
|
+
export * from './shared/consts.js';
|
|
14
|
+
export * from './shared/elements.js';
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/shared/consts.d.ts
CHANGED
|
@@ -18,6 +18,12 @@
|
|
|
18
18
|
* second key here for the same English word would only be the drift the
|
|
19
19
|
* manifest guard exists to catch.
|
|
20
20
|
*/
|
|
21
|
+
/**
|
|
22
|
+
* The boards' chrome font. Declared here rather than in `utils.ts`, which
|
|
23
|
+
* re-exports the editor's `refScale`, so the editor-free entry (`headless.ts`)
|
|
24
|
+
* can carry it to a board's declaration.
|
|
25
|
+
*/
|
|
26
|
+
export declare const FONT_FAMILY = "Inter, sans-serif";
|
|
21
27
|
/** Square sticky side (px, canvas reference). */
|
|
22
28
|
export declare const STICKY_SIZE = 120;
|
|
23
29
|
/** Faux drop-shadow offset + colour (a plain offset rect behind the sticky). */
|
|
@@ -229,4 +235,4 @@ export declare const MOVEMENT_COLOR = "#ff3333";
|
|
|
229
235
|
* three values — one declaration, so a DDD caption and the legend line that
|
|
230
236
|
* explains it cannot drift apart.
|
|
231
237
|
*/
|
|
232
|
-
export { LABEL_COLOR, LABEL_FONT, LABEL_FONT_SIZE, } from '@formicoidea/labre-core/
|
|
238
|
+
export { LABEL_COLOR, LABEL_FONT, LABEL_FONT_SIZE, } from '@formicoidea/labre-core/interchange';
|
package/dist/shared/consts.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NOTATION_NEUTRALS } from '@formicoidea/labre-core/shared/
|
|
1
|
+
import { NOTATION_NEUTRALS } from '@formicoidea/labre-core/shared/headless';
|
|
2
2
|
/**
|
|
3
3
|
* Shared DDD palette and sizes. Every tool composes the same irreducible units
|
|
4
4
|
* (sticky, dot, bubble, connector, label) from these presets — no duplicated
|
|
@@ -19,6 +19,12 @@ import { NOTATION_NEUTRALS } from '@formicoidea/labre-core/shared/consts';
|
|
|
19
19
|
* second key here for the same English word would only be the drift the
|
|
20
20
|
* manifest guard exists to catch.
|
|
21
21
|
*/
|
|
22
|
+
/**
|
|
23
|
+
* The boards' chrome font. Declared here rather than in `utils.ts`, which
|
|
24
|
+
* re-exports the editor's `refScale`, so the editor-free entry (`headless.ts`)
|
|
25
|
+
* can carry it to a board's declaration.
|
|
26
|
+
*/
|
|
27
|
+
export const FONT_FAMILY = 'Inter, sans-serif';
|
|
22
28
|
/** Square sticky side (px, canvas reference). */
|
|
23
29
|
export const STICKY_SIZE = 120;
|
|
24
30
|
/** Faux drop-shadow offset + colour (a plain offset rect behind the sticky). */
|
|
@@ -221,4 +227,4 @@ export const MOVEMENT_COLOR = '#ff3333';
|
|
|
221
227
|
* three values — one declaration, so a DDD caption and the legend line that
|
|
222
228
|
* explains it cannot drift apart.
|
|
223
229
|
*/
|
|
224
|
-
export { LABEL_COLOR, LABEL_FONT, LABEL_FONT_SIZE, } from '@formicoidea/labre-core/
|
|
230
|
+
export { LABEL_COLOR, LABEL_FONT, LABEL_FONT_SIZE, } from '@formicoidea/labre-core/interchange';
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { SerializedElementProps, ToolboxPoint } from '@formicoidea/labre-core/interchange';
|
|
2
|
+
import { TextFitMode } from '@formicoidea/labre-core/model/headless';
|
|
3
|
+
export interface ShapeOpts {
|
|
4
|
+
shapeType?: 'rect' | 'ellipse' | 'diamond';
|
|
5
|
+
fill: string;
|
|
6
|
+
/**
|
|
7
|
+
* Semantic role (`<framework>:<role>`) stamped on the shape, so a validation
|
|
8
|
+
* rule can recognise it. `undefined` writes NOTHING — no `role` key is
|
|
9
|
+
* persisted and the artefact stays a neutral drawing, which is what every
|
|
10
|
+
* caller that does not pass one keeps getting and what every DDD artefact
|
|
11
|
+
* created before this parameter existed already is.
|
|
12
|
+
*/
|
|
13
|
+
role?: string;
|
|
14
|
+
stroke?: string;
|
|
15
|
+
strokeWidth?: number;
|
|
16
|
+
radius?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Shape-owned centred label. The text belongs to the shape itself (edited
|
|
19
|
+
* by double-click, moves/resizes with it) with the given text-fit mode —
|
|
20
|
+
* `contained` mimics a physical post-it.
|
|
21
|
+
*/
|
|
22
|
+
label?: {
|
|
23
|
+
text: string;
|
|
24
|
+
color: string;
|
|
25
|
+
fontFamily: string;
|
|
26
|
+
fontSize: number;
|
|
27
|
+
fit: TextFitMode;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The props a DDD shape is CREATED with, its label's text as a string. The
|
|
32
|
+
* prefabs' `dddShapeProps` is this with the text as a `Y.Text`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function dddShapeElement(x: number, y: number, w: number, h: number, opts: ShapeOpts): SerializedElementProps;
|
|
35
|
+
/**
|
|
36
|
+
* What a Core Domain DOT is, as shape options — read by the builder below and
|
|
37
|
+
* by the morph, so the two can never disagree about what a platform
|
|
38
|
+
* sub-domain looks like.
|
|
39
|
+
*/
|
|
40
|
+
export declare function dotShapeOpts(fill: string, role?: string): ShapeOpts;
|
|
41
|
+
/** What a Team Topologies MARKER square is, the same way. */
|
|
42
|
+
export declare function markerShapeOpts(fill: string, role?: string): ShapeOpts;
|
|
43
|
+
export interface StickyOpts {
|
|
44
|
+
fill: string;
|
|
45
|
+
text: string;
|
|
46
|
+
label: string;
|
|
47
|
+
shapeType?: 'rect' | 'diamond';
|
|
48
|
+
size?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Stamped on the FACE, never on the shadow: the face is the artefact — it
|
|
51
|
+
* is what carries the words, what a connector attaches to and what the
|
|
52
|
+
* grammar rules read. The shadow is ink.
|
|
53
|
+
*/
|
|
54
|
+
role?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A post-it whose face is at `at`: the faux-shadow rect, the coloured face
|
|
58
|
+
* whose label is its OWN shape text in `contained` fit mode, and their group.
|
|
59
|
+
*/
|
|
60
|
+
export declare function stickyElements(at: ToolboxPoint, opts: StickyOpts, local?: string): SerializedElementProps[];
|
|
61
|
+
/**
|
|
62
|
+
* A Context Map bounded-context bubble at `at`: a rounded pill whose label is
|
|
63
|
+
* the pill's own shape text in `overflow` fit mode (fixed pill, fixed font — a
|
|
64
|
+
* long context name may spill out rather than deform the map).
|
|
65
|
+
*/
|
|
66
|
+
export declare function bubbleElement(at: ToolboxPoint, label: string, role?: string, local?: string): SerializedElementProps;
|
|
67
|
+
/**
|
|
68
|
+
* A Core Domain dot at `at`; with a label, the caption to its right and the
|
|
69
|
+
* group of the two. The role rides on the ELLIPSE, never on the group.
|
|
70
|
+
*/
|
|
71
|
+
export declare function dotElements(at: ToolboxPoint, fill: string, label?: string, role?: string, local?: string): SerializedElementProps[];
|
|
72
|
+
export interface MarkerOpts {
|
|
73
|
+
fill: string;
|
|
74
|
+
letter: string;
|
|
75
|
+
label?: string;
|
|
76
|
+
role?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A Team Topologies interaction-mode marker whose square is at `at`: the
|
|
80
|
+
* square, its centred letter, the caption beside it when given, and the group.
|
|
81
|
+
* The role rides on the SQUARE: the letter is its glyph and the word beside it
|
|
82
|
+
* is a caption.
|
|
83
|
+
*/
|
|
84
|
+
export declare function markerElements(at: ToolboxPoint, opts: MarkerOpts, local?: string): SerializedElementProps[];
|
|
85
|
+
/**
|
|
86
|
+
* A cloud (Big Ball of Mud / general-purpose boundary) at `at`: a dense
|
|
87
|
+
* closed polygon; with a label, the text across it and the group of the two.
|
|
88
|
+
* The role rides on the POLYGON, never on the group: the polygon is what a
|
|
89
|
+
* relationship binds to and what the legend scan meets.
|
|
90
|
+
*/
|
|
91
|
+
export declare function cloudElements(at: ToolboxPoint, label?: string, role?: string, local?: string): SerializedElementProps[];
|
|
92
|
+
/** A connector end: an element (or local) id, or a free point. */
|
|
93
|
+
export type DddConnectorEnd = {
|
|
94
|
+
id: string;
|
|
95
|
+
} | {
|
|
96
|
+
position: [number, number];
|
|
97
|
+
};
|
|
98
|
+
export interface DddConnectorOpts {
|
|
99
|
+
rearArrow?: boolean;
|
|
100
|
+
dashed?: boolean;
|
|
101
|
+
stroke?: string;
|
|
102
|
+
strokeWidth?: number;
|
|
103
|
+
/** Edge role; `undefined` leaves the connector a neutral line. */
|
|
104
|
+
role?: string;
|
|
105
|
+
/** The words riding on the line; none when absent or blank. */
|
|
106
|
+
label?: string;
|
|
107
|
+
}
|
|
108
|
+
/** A relationship connector (the single connector unit reused for all patterns). */
|
|
109
|
+
export declare function dddConnectorElement(source: DddConnectorEnd, target: DddConnectorEnd, opts?: DddConnectorOpts): SerializedElementProps;
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { ConnectorMode, FontWeight, PointStyle, ShapeStyle, StrokeStyle, TextFitMode, } from '@formicoidea/labre-core/model/headless';
|
|
2
|
+
import { NOTATION_NEUTRALS } from '@formicoidea/labre-core/shared/headless';
|
|
3
|
+
import { Bound } from '@formicoidea/labre-core/global/gfx';
|
|
4
|
+
import { CLOUD, CLOUD_VERTICES, CM_BUBBLE, DOT_SIZE, LABEL_COLOR, LABEL_FONT, LABEL_FONT_SIZE, MARKER_SIZE, SHADOW_COLOR, SHADOW_OFFSET, STICKY_FONT, STICKY_FONT_SIZE, STICKY_RADIUS, STICKY_SIZE, } from './consts.js';
|
|
5
|
+
/**
|
|
6
|
+
* The DDD artefacts as PURE builders (`docs/adr/0045`): the elements a
|
|
7
|
+
* sticky, a bubble, a dot, a marker, a cloud or a relationship is made of, as
|
|
8
|
+
* serialized props, with no editor behind them. The prefabs (`prefabs.ts`)
|
|
9
|
+
* write these through `surface.addElement`, and each board's toolbox (its
|
|
10
|
+
* `./interchange` entry) hands them to a host with no editor — one assembly
|
|
11
|
+
* per artefact, shared by the three boards, which is what this package is for.
|
|
12
|
+
*
|
|
13
|
+
* The contract is a reader's (ADR 0012 D3): painting order, LOCAL ids, each
|
|
14
|
+
* composite's members before the group that holds them, the group last. `at`
|
|
15
|
+
* is the top-left of the artefact's own box (the sticky's face, the dot, the
|
|
16
|
+
* marker's square); a caption written beside it lies outside that box.
|
|
17
|
+
*
|
|
18
|
+
* A builder writes the text it is given and never translates it: the seed in
|
|
19
|
+
* the host's language is resolved by the editor's creation site (ADR 0023).
|
|
20
|
+
* A shape's text is a plain string here; the shape model turns it into a
|
|
21
|
+
* `Y.Text` on `addElement` (`ShapeElementModel.propsToY`), so the stored
|
|
22
|
+
* element is the same whichever side built it.
|
|
23
|
+
*/
|
|
24
|
+
const NO_STROKE = '#00000000';
|
|
25
|
+
/** The ink every Core Domain artefact is outlined with: the shared scale's. */
|
|
26
|
+
const ARTEFACT_STROKE = NOTATION_NEUTRALS.ink;
|
|
27
|
+
/**
|
|
28
|
+
* The props a DDD shape is CREATED with, its label's text as a string. The
|
|
29
|
+
* prefabs' `dddShapeProps` is this with the text as a `Y.Text`.
|
|
30
|
+
*/
|
|
31
|
+
export function dddShapeElement(x, y, w, h, opts) {
|
|
32
|
+
const { shapeType = 'rect', fill, stroke = NO_STROKE, strokeWidth = 0, radius = 0, label, role, } = opts;
|
|
33
|
+
return {
|
|
34
|
+
type: 'shape',
|
|
35
|
+
// `undefined` writes nothing: a neutral artefact keeps no `role` key.
|
|
36
|
+
role,
|
|
37
|
+
shapeType,
|
|
38
|
+
filled: true,
|
|
39
|
+
fillColor: fill,
|
|
40
|
+
strokeColor: stroke,
|
|
41
|
+
strokeWidth,
|
|
42
|
+
shapeStyle: ShapeStyle.General,
|
|
43
|
+
roughness: 0,
|
|
44
|
+
radius,
|
|
45
|
+
xywh: new Bound(x, y, w, h).serialize(),
|
|
46
|
+
...(label
|
|
47
|
+
? {
|
|
48
|
+
text: label.text,
|
|
49
|
+
color: label.color,
|
|
50
|
+
fontFamily: label.fontFamily,
|
|
51
|
+
fontSize: label.fontSize,
|
|
52
|
+
textAlign: 'center',
|
|
53
|
+
textFitMode: label.fit,
|
|
54
|
+
}
|
|
55
|
+
: {}),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** A canvas TEXT element: a caption beside an artefact, or a marker's letter. */
|
|
59
|
+
function textElement(id, x, y, w, text, color, fontFamily, fontSize, textAlign = 'center') {
|
|
60
|
+
return {
|
|
61
|
+
type: 'text',
|
|
62
|
+
id,
|
|
63
|
+
text,
|
|
64
|
+
color,
|
|
65
|
+
fontFamily,
|
|
66
|
+
fontSize,
|
|
67
|
+
textAlign,
|
|
68
|
+
fontWeight: FontWeight.Regular,
|
|
69
|
+
xywh: new Bound(x, y, w, fontSize + 10).serialize(),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** The group holding `members`, written after them. */
|
|
73
|
+
function groupOf(id, members) {
|
|
74
|
+
return {
|
|
75
|
+
type: 'group',
|
|
76
|
+
id,
|
|
77
|
+
children: Object.fromEntries(members.map(m => [m.id, true])),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* What a Core Domain DOT is, as shape options — read by the builder below and
|
|
82
|
+
* by the morph, so the two can never disagree about what a platform
|
|
83
|
+
* sub-domain looks like.
|
|
84
|
+
*/
|
|
85
|
+
export function dotShapeOpts(fill, role) {
|
|
86
|
+
return {
|
|
87
|
+
shapeType: 'ellipse',
|
|
88
|
+
fill,
|
|
89
|
+
stroke: ARTEFACT_STROKE,
|
|
90
|
+
strokeWidth: 1.5,
|
|
91
|
+
role,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** What a Team Topologies MARKER square is, the same way. */
|
|
95
|
+
export function markerShapeOpts(fill, role) {
|
|
96
|
+
return {
|
|
97
|
+
fill,
|
|
98
|
+
stroke: ARTEFACT_STROKE,
|
|
99
|
+
strokeWidth: 1.5,
|
|
100
|
+
radius: 4,
|
|
101
|
+
role,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* A post-it whose face is at `at`: the faux-shadow rect, the coloured face
|
|
106
|
+
* whose label is its OWN shape text in `contained` fit mode, and their group.
|
|
107
|
+
*/
|
|
108
|
+
export function stickyElements(at, opts, local = 'sticky') {
|
|
109
|
+
const { fill, text, label, shapeType = 'rect', size = STICKY_SIZE, role, } = opts;
|
|
110
|
+
const radius = shapeType === 'rect' ? STICKY_RADIUS : 0;
|
|
111
|
+
const members = [
|
|
112
|
+
{
|
|
113
|
+
...dddShapeElement(at.x + SHADOW_OFFSET, at.y + SHADOW_OFFSET, size, size, { shapeType, fill: SHADOW_COLOR, radius }),
|
|
114
|
+
id: `${local}:shadow`,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
...dddShapeElement(at.x, at.y, size, size, {
|
|
118
|
+
shapeType,
|
|
119
|
+
fill,
|
|
120
|
+
radius,
|
|
121
|
+
role,
|
|
122
|
+
label: {
|
|
123
|
+
text: label,
|
|
124
|
+
color: text,
|
|
125
|
+
fontFamily: STICKY_FONT,
|
|
126
|
+
fontSize: STICKY_FONT_SIZE,
|
|
127
|
+
fit: TextFitMode.Contained,
|
|
128
|
+
},
|
|
129
|
+
}),
|
|
130
|
+
id: `${local}:face`,
|
|
131
|
+
},
|
|
132
|
+
];
|
|
133
|
+
return [...members, groupOf(`${local}:group`, members)];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* A Context Map bounded-context bubble at `at`: a rounded pill whose label is
|
|
137
|
+
* the pill's own shape text in `overflow` fit mode (fixed pill, fixed font — a
|
|
138
|
+
* long context name may spill out rather than deform the map).
|
|
139
|
+
*/
|
|
140
|
+
export function bubbleElement(at, label, role, local = 'bubble') {
|
|
141
|
+
const { w, h, radius, fill, stroke, text } = CM_BUBBLE;
|
|
142
|
+
return {
|
|
143
|
+
...dddShapeElement(at.x, at.y, w, h, {
|
|
144
|
+
fill,
|
|
145
|
+
stroke,
|
|
146
|
+
strokeWidth: 1.5,
|
|
147
|
+
radius,
|
|
148
|
+
role,
|
|
149
|
+
label: {
|
|
150
|
+
text: label,
|
|
151
|
+
color: text,
|
|
152
|
+
fontFamily: LABEL_FONT,
|
|
153
|
+
fontSize: LABEL_FONT_SIZE,
|
|
154
|
+
fit: TextFitMode.Overflow,
|
|
155
|
+
},
|
|
156
|
+
}),
|
|
157
|
+
id: local,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* A Core Domain dot at `at`; with a label, the caption to its right and the
|
|
162
|
+
* group of the two. The role rides on the ELLIPSE, never on the group.
|
|
163
|
+
*/
|
|
164
|
+
export function dotElements(at, fill, label, role, local = 'dot') {
|
|
165
|
+
const d = DOT_SIZE;
|
|
166
|
+
const dot = {
|
|
167
|
+
...dddShapeElement(at.x, at.y, d, d, dotShapeOpts(fill, role)),
|
|
168
|
+
id: `${local}:dot`,
|
|
169
|
+
};
|
|
170
|
+
if (!label)
|
|
171
|
+
return [dot];
|
|
172
|
+
const caption = textElement(`${local}:caption`, at.x + d + 6, at.y + d / 2 - LABEL_FONT_SIZE / 2, 170, label, LABEL_COLOR, LABEL_FONT, LABEL_FONT_SIZE, 'left');
|
|
173
|
+
return [dot, caption, groupOf(`${local}:group`, [dot, caption])];
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* A Team Topologies interaction-mode marker whose square is at `at`: the
|
|
177
|
+
* square, its centred letter, the caption beside it when given, and the group.
|
|
178
|
+
* The role rides on the SQUARE: the letter is its glyph and the word beside it
|
|
179
|
+
* is a caption.
|
|
180
|
+
*/
|
|
181
|
+
export function markerElements(at, opts, local = 'marker') {
|
|
182
|
+
const { fill, letter, label, role } = opts;
|
|
183
|
+
const s = MARKER_SIZE;
|
|
184
|
+
const members = [
|
|
185
|
+
{
|
|
186
|
+
...dddShapeElement(at.x, at.y, s, s, markerShapeOpts(fill, role)),
|
|
187
|
+
id: `${local}:square`,
|
|
188
|
+
},
|
|
189
|
+
textElement(`${local}:letter`, at.x, at.y + s / 2 - 9, s, letter, NOTATION_NEUTRALS.ink, LABEL_FONT, 15),
|
|
190
|
+
];
|
|
191
|
+
if (label) {
|
|
192
|
+
members.push(textElement(`${local}:caption`, at.x + s + 6, at.y + s / 2 - LABEL_FONT_SIZE / 2, 150, label, LABEL_COLOR, LABEL_FONT, LABEL_FONT_SIZE, 'left'));
|
|
193
|
+
}
|
|
194
|
+
return [...members, groupOf(`${local}:group`, members)];
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* A cloud (Big Ball of Mud / general-purpose boundary) at `at`: a dense
|
|
198
|
+
* closed polygon; with a label, the text across it and the group of the two.
|
|
199
|
+
* The role rides on the POLYGON, never on the group: the polygon is what a
|
|
200
|
+
* relationship binds to and what the legend scan meets.
|
|
201
|
+
*/
|
|
202
|
+
export function cloudElements(at, label, role, local = 'cloud') {
|
|
203
|
+
const { w, h, fill, stroke } = CLOUD;
|
|
204
|
+
const cloud = {
|
|
205
|
+
type: 'shape',
|
|
206
|
+
id: `${local}:cloud`,
|
|
207
|
+
shapeType: 'polygon',
|
|
208
|
+
vertices: CLOUD_VERTICES,
|
|
209
|
+
isClosed: true,
|
|
210
|
+
filled: true,
|
|
211
|
+
fillColor: fill,
|
|
212
|
+
strokeColor: stroke,
|
|
213
|
+
strokeWidth: 1.5,
|
|
214
|
+
shapeStyle: ShapeStyle.General,
|
|
215
|
+
roughness: 0,
|
|
216
|
+
xywh: new Bound(at.x, at.y, w, h).serialize(),
|
|
217
|
+
...(role ? { role } : {}),
|
|
218
|
+
};
|
|
219
|
+
if (!label)
|
|
220
|
+
return [cloud];
|
|
221
|
+
const caption = textElement(`${local}:caption`, at.x + 12, at.y + h / 2 - LABEL_FONT_SIZE / 2, w - 24, label, NOTATION_NEUTRALS.ink, LABEL_FONT, LABEL_FONT_SIZE);
|
|
222
|
+
return [cloud, caption, groupOf(`${local}:group`, [cloud, caption])];
|
|
223
|
+
}
|
|
224
|
+
/** A relationship connector (the single connector unit reused for all patterns). */
|
|
225
|
+
export function dddConnectorElement(source, target, opts = {}) {
|
|
226
|
+
const { rearArrow = false, dashed = false, stroke = LABEL_COLOR, strokeWidth = 2, role, label, } = opts;
|
|
227
|
+
return {
|
|
228
|
+
type: 'connector',
|
|
229
|
+
role,
|
|
230
|
+
mode: ConnectorMode.Straight,
|
|
231
|
+
stroke,
|
|
232
|
+
strokeWidth,
|
|
233
|
+
strokeStyle: dashed ? StrokeStyle.Dash : StrokeStyle.Solid,
|
|
234
|
+
frontEndpointStyle: PointStyle.None,
|
|
235
|
+
rearEndpointStyle: rearArrow ? PointStyle.Arrow : PointStyle.None,
|
|
236
|
+
source,
|
|
237
|
+
target,
|
|
238
|
+
...(label?.trim() ? { text: label.trim() } : {}),
|
|
239
|
+
};
|
|
240
|
+
}
|
package/dist/shared/prefabs.d.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import { TextFitMode } from '@formicoidea/labre-core/model';
|
|
2
1
|
import type { BlockStdScope } from '@formicoidea/labre-core/std';
|
|
3
2
|
import { type GfxController } from '@formicoidea/labre-core/std/gfx';
|
|
3
|
+
import { type ShapeOpts } from './elements.js';
|
|
4
4
|
/**
|
|
5
5
|
* Irreducible reusable units composed by all three DDD sub-menus. Each helper
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* writes the elements its pure builder returns (`elements.ts`,
|
|
7
|
+
* `docs/adr/0045`) through native `surface.addElement` (shape / text /
|
|
8
|
+
* connector) and the group command; nothing here defines a new element type,
|
|
9
|
+
* so the same builders back Event Storming stickies, Context Map bubbles +
|
|
10
|
+
* relationships and Core Domain dots + arrows, here and on a host with no
|
|
11
|
+
* editor.
|
|
12
|
+
*
|
|
13
|
+
* What stays here is what only an editor has: the viewport centre the
|
|
14
|
+
* prefabs are placed around, and the group command, which names the group
|
|
15
|
+
* ("Group N", resolved in the host's language) and stamps its user layer.
|
|
9
16
|
*/
|
|
10
17
|
type Surface = NonNullable<GfxController['surface']>;
|
|
11
18
|
/**
|
|
@@ -18,36 +25,9 @@ type Surface = NonNullable<GfxController['surface']>;
|
|
|
18
25
|
export declare function placeDddElement(std: BlockStdScope, build: (surface: Surface, cx: number, cy: number) => string): void;
|
|
19
26
|
/** Group several element ids; returns the group id (or the first id on failure). */
|
|
20
27
|
export declare function groupIds(std: BlockStdScope, ids: string[]): string;
|
|
21
|
-
export interface ShapeOpts {
|
|
22
|
-
shapeType?: 'rect' | 'ellipse' | 'diamond';
|
|
23
|
-
fill: string;
|
|
24
|
-
/**
|
|
25
|
-
* Semantic role (`<framework>:<role>`) stamped on the shape, so a validation
|
|
26
|
-
* rule can recognise it. `undefined` writes NOTHING — no `role` key is
|
|
27
|
-
* persisted and the artefact stays a neutral drawing, which is what every
|
|
28
|
-
* caller that does not pass one keeps getting and what every DDD artefact
|
|
29
|
-
* created before this parameter existed already is.
|
|
30
|
-
*/
|
|
31
|
-
role?: string;
|
|
32
|
-
stroke?: string;
|
|
33
|
-
strokeWidth?: number;
|
|
34
|
-
radius?: number;
|
|
35
|
-
/**
|
|
36
|
-
* Shape-owned centred label. The text belongs to the shape itself (edited
|
|
37
|
-
* by double-click, moves/resizes with it) with the given text-fit mode —
|
|
38
|
-
* `contained` mimics a physical post-it.
|
|
39
|
-
*/
|
|
40
|
-
label?: {
|
|
41
|
-
text: string;
|
|
42
|
-
color: string;
|
|
43
|
-
fontFamily: string;
|
|
44
|
-
fontSize: number;
|
|
45
|
-
fit: TextFitMode;
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
28
|
/**
|
|
49
|
-
* The props a DDD shape is CREATED with, as a record — the write of
|
|
50
|
-
*
|
|
29
|
+
* The props a DDD shape is CREATED with, as a record — the write of the
|
|
30
|
+
* prefabs, minus the write.
|
|
51
31
|
*
|
|
52
32
|
* Split out for the Core Domain morph, and for the reason C4's `presets.ts`
|
|
53
33
|
* gives: a kind's appearance is written by the preset of the kind it was created
|
|
@@ -85,14 +65,6 @@ export declare function addSticky(surface: Surface, std: BlockStdScope, cx: numb
|
|
|
85
65
|
* long context name may spill out rather than deform the map).
|
|
86
66
|
*/
|
|
87
67
|
export declare function addBubble(surface: Surface, cx: number, cy: number, label: string, role?: string): string;
|
|
88
|
-
/**
|
|
89
|
-
* What a Core Domain DOT is, as shape options — read by the creation site below
|
|
90
|
-
* and by the morph, so the two can never disagree about what a platform
|
|
91
|
-
* sub-domain looks like. See {@link dddShapeProps}.
|
|
92
|
-
*/
|
|
93
|
-
export declare function dotShapeOpts(fill: string, role?: string): ShapeOpts;
|
|
94
|
-
/** What a Team Topologies MARKER square is, the same way. */
|
|
95
|
-
export declare function markerShapeOpts(fill: string, role?: string): ShapeOpts;
|
|
96
68
|
/** A Core Domain dot (sub-domain / bounded context); optional label to its right. */
|
|
97
69
|
export declare function addDot(surface: Surface, std: BlockStdScope, cx: number, cy: number, fill: string, label?: string,
|
|
98
70
|
/** Stamped on the ELLIPSE, never on the group: the dot is the artefact. */
|
package/dist/shared/prefabs.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import { DefaultTool } from '@formicoidea/labre-core/blocks/surface';
|
|
1
|
+
import { DefaultTool, } from '@formicoidea/labre-core/blocks/surface';
|
|
2
2
|
import { createGroupCommand } from '@formicoidea/labre-core/gfx/group';
|
|
3
|
-
import { ConnectorMode, FontWeight, PointStyle, ShapeStyle, StrokeStyle, TextFitMode, } from '@formicoidea/labre-core/model';
|
|
4
|
-
import { NOTATION_NEUTRALS } from '@formicoidea/labre-core/shared/consts';
|
|
5
|
-
import { Bound } from '@formicoidea/labre-core/global/gfx';
|
|
6
3
|
import { GfxControllerIdentifier } from '@formicoidea/labre-core/std/gfx';
|
|
7
4
|
import * as Y from 'yjs';
|
|
8
|
-
import { CLOUD,
|
|
9
|
-
|
|
5
|
+
import { CLOUD, CM_BUBBLE, DOT_SIZE, MARKER_SIZE, STICKY_SIZE, } from './consts.js';
|
|
6
|
+
import { bubbleElement, cloudElements, dddConnectorElement, dddShapeElement, dotElements, markerElements, stickyElements, } from './elements.js';
|
|
10
7
|
/**
|
|
11
8
|
* Build one DDD artefact at the viewport centre and select it, leaving the
|
|
12
9
|
* palette open so several can be added in a row. This is the old
|
|
@@ -31,8 +28,41 @@ export function groupIds(std, ids) {
|
|
|
31
28
|
return result.groupId || ids[0];
|
|
32
29
|
}
|
|
33
30
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
31
|
+
* A shape's label as the `Y.Text` the prefabs have always written. The shape
|
|
32
|
+
* model's `propsToY` makes the same `Y.Text` of a string, so this changes
|
|
33
|
+
* nothing stored; it keeps what `addElement` receives from a prefab what it
|
|
34
|
+
* was before the builders existed.
|
|
35
|
+
*/
|
|
36
|
+
function withYText(props) {
|
|
37
|
+
return props.type === 'shape' && typeof props.text === 'string'
|
|
38
|
+
? { ...props, text: new Y.Text(props.text) }
|
|
39
|
+
: props;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Write a builder's elements in order, minting real ids for the local ones;
|
|
43
|
+
* a group goes through the group command with its members' minted ids.
|
|
44
|
+
* Returns the id of the last element: the group of a composite, the element
|
|
45
|
+
* itself otherwise.
|
|
46
|
+
*/
|
|
47
|
+
function addElements(surface, std, elements) {
|
|
48
|
+
const minted = new Map();
|
|
49
|
+
let last = '';
|
|
50
|
+
for (const { id: local, ...props } of elements) {
|
|
51
|
+
if (props.type === 'group' && std) {
|
|
52
|
+
const children = Object.keys(props.children);
|
|
53
|
+
last = groupIds(std, children.map(child => minted.get(child) ?? child));
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
last = surface.addElement(withYText(props));
|
|
57
|
+
}
|
|
58
|
+
if (typeof local === 'string')
|
|
59
|
+
minted.set(local, last);
|
|
60
|
+
}
|
|
61
|
+
return last;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The props a DDD shape is CREATED with, as a record — the write of the
|
|
65
|
+
* prefabs, minus the write.
|
|
36
66
|
*
|
|
37
67
|
* Split out for the Core Domain morph, and for the reason C4's `presets.ts`
|
|
38
68
|
* gives: a kind's appearance is written by the preset of the kind it was created
|
|
@@ -42,46 +72,7 @@ export function groupIds(std, ids) {
|
|
|
42
72
|
* element.
|
|
43
73
|
*/
|
|
44
74
|
export function dddShapeProps(x, y, w, h, opts) {
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
type: 'shape',
|
|
48
|
-
// `undefined` writes nothing: a neutral artefact keeps no `role` key.
|
|
49
|
-
role,
|
|
50
|
-
shapeType,
|
|
51
|
-
filled: true,
|
|
52
|
-
fillColor: fill,
|
|
53
|
-
strokeColor: stroke,
|
|
54
|
-
strokeWidth,
|
|
55
|
-
shapeStyle: ShapeStyle.General,
|
|
56
|
-
roughness: 0,
|
|
57
|
-
radius,
|
|
58
|
-
xywh: new Bound(x, y, w, h).serialize(),
|
|
59
|
-
...(label
|
|
60
|
-
? {
|
|
61
|
-
text: new Y.Text(label.text),
|
|
62
|
-
color: label.color,
|
|
63
|
-
fontFamily: label.fontFamily,
|
|
64
|
-
fontSize: label.fontSize,
|
|
65
|
-
textAlign: 'center',
|
|
66
|
-
textFitMode: label.fit,
|
|
67
|
-
}
|
|
68
|
-
: {}),
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
function addShape(surface, x, y, w, h, opts) {
|
|
72
|
-
return surface.addElement(dddShapeProps(x, y, w, h, opts));
|
|
73
|
-
}
|
|
74
|
-
function addText(surface, x, y, w, text, color, fontFamily, fontSize, textAlign = 'center', bold = false) {
|
|
75
|
-
return surface.addElement({
|
|
76
|
-
type: 'text',
|
|
77
|
-
text,
|
|
78
|
-
color,
|
|
79
|
-
fontFamily,
|
|
80
|
-
fontSize,
|
|
81
|
-
textAlign,
|
|
82
|
-
fontWeight: bold ? FontWeight.SemiBold : FontWeight.Regular,
|
|
83
|
-
xywh: new Bound(x, y, w, fontSize + 10).serialize(),
|
|
84
|
-
});
|
|
75
|
+
return withYText(dddShapeElement(x, y, w, h, opts));
|
|
85
76
|
}
|
|
86
77
|
/**
|
|
87
78
|
* A post-it: faux-shadow rect + coloured face whose label is the face's OWN
|
|
@@ -91,28 +82,8 @@ function addText(surface, x, y, w, text, color, fontFamily, fontSize, textAlign
|
|
|
91
82
|
* text element; they keep working untouched.)
|
|
92
83
|
*/
|
|
93
84
|
export function addSticky(surface, std, cx, cy, opts) {
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
const radius = shapeType === 'rect' ? STICKY_RADIUS : 0;
|
|
97
|
-
const shadow = addShape(surface, cx - half + SHADOW_OFFSET, cy - half + SHADOW_OFFSET, size, size, {
|
|
98
|
-
shapeType,
|
|
99
|
-
fill: SHADOW_COLOR,
|
|
100
|
-
radius,
|
|
101
|
-
});
|
|
102
|
-
const face = addShape(surface, cx - half, cy - half, size, size, {
|
|
103
|
-
shapeType,
|
|
104
|
-
fill,
|
|
105
|
-
radius,
|
|
106
|
-
role,
|
|
107
|
-
label: {
|
|
108
|
-
text: label,
|
|
109
|
-
color: text,
|
|
110
|
-
fontFamily: STICKY_FONT,
|
|
111
|
-
fontSize: STICKY_FONT_SIZE,
|
|
112
|
-
fit: TextFitMode.Contained,
|
|
113
|
-
},
|
|
114
|
-
});
|
|
115
|
-
return groupIds(std, [shadow, face]);
|
|
85
|
+
const half = (opts.size ?? STICKY_SIZE) / 2;
|
|
86
|
+
return addElements(surface, std, stickyElements({ x: cx - half, y: cy - half }, opts));
|
|
116
87
|
}
|
|
117
88
|
/**
|
|
118
89
|
* A Context Map bounded-context bubble: a rounded pill whose label is the
|
|
@@ -120,74 +91,21 @@ export function addSticky(surface, std, cx, cy, opts) {
|
|
|
120
91
|
* long context name may spill out rather than deform the map).
|
|
121
92
|
*/
|
|
122
93
|
export function addBubble(surface, cx, cy, label, role) {
|
|
123
|
-
const { w, h
|
|
124
|
-
return
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
strokeWidth: 1.5,
|
|
128
|
-
radius,
|
|
129
|
-
role,
|
|
130
|
-
label: {
|
|
131
|
-
text: label,
|
|
132
|
-
color: text,
|
|
133
|
-
fontFamily: LABEL_FONT,
|
|
134
|
-
fontSize: LABEL_FONT_SIZE,
|
|
135
|
-
fit: TextFitMode.Overflow,
|
|
136
|
-
},
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
/** The ink every Core Domain artefact is outlined with: the shared scale's. */
|
|
140
|
-
const ARTEFACT_STROKE = NOTATION_NEUTRALS.ink;
|
|
141
|
-
/**
|
|
142
|
-
* What a Core Domain DOT is, as shape options — read by the creation site below
|
|
143
|
-
* and by the morph, so the two can never disagree about what a platform
|
|
144
|
-
* sub-domain looks like. See {@link dddShapeProps}.
|
|
145
|
-
*/
|
|
146
|
-
export function dotShapeOpts(fill, role) {
|
|
147
|
-
return {
|
|
148
|
-
shapeType: 'ellipse',
|
|
149
|
-
fill,
|
|
150
|
-
stroke: ARTEFACT_STROKE,
|
|
151
|
-
strokeWidth: 1.5,
|
|
152
|
-
role,
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
/** What a Team Topologies MARKER square is, the same way. */
|
|
156
|
-
export function markerShapeOpts(fill, role) {
|
|
157
|
-
return {
|
|
158
|
-
fill,
|
|
159
|
-
stroke: ARTEFACT_STROKE,
|
|
160
|
-
strokeWidth: 1.5,
|
|
161
|
-
radius: 4,
|
|
162
|
-
role,
|
|
163
|
-
};
|
|
94
|
+
const { w, h } = CM_BUBBLE;
|
|
95
|
+
return addElements(surface, undefined, [
|
|
96
|
+
bubbleElement({ x: cx - w / 2, y: cy - h / 2 }, label, role),
|
|
97
|
+
]);
|
|
164
98
|
}
|
|
165
99
|
/** A Core Domain dot (sub-domain / bounded context); optional label to its right. */
|
|
166
100
|
export function addDot(surface, std, cx, cy, fill, label,
|
|
167
101
|
/** Stamped on the ELLIPSE, never on the group: the dot is the artefact. */
|
|
168
102
|
role) {
|
|
169
103
|
const d = DOT_SIZE;
|
|
170
|
-
|
|
171
|
-
if (!label)
|
|
172
|
-
return dot;
|
|
173
|
-
const lbl = addText(surface, cx + d / 2 + 6, cy - LABEL_FONT_SIZE / 2, 170, label, LABEL_COLOR, LABEL_FONT, LABEL_FONT_SIZE, 'left');
|
|
174
|
-
return groupIds(std, [dot, lbl]);
|
|
104
|
+
return addElements(surface, std, dotElements({ x: cx - d / 2, y: cy - d / 2 }, fill, label, role));
|
|
175
105
|
}
|
|
176
106
|
/** A relationship connector (the single connector unit reused for all patterns). */
|
|
177
107
|
export function addConnector(surface, x1, y1, x2, y2, opts = {}) {
|
|
178
|
-
|
|
179
|
-
return surface.addElement({
|
|
180
|
-
type: 'connector',
|
|
181
|
-
role,
|
|
182
|
-
mode: ConnectorMode.Straight,
|
|
183
|
-
stroke,
|
|
184
|
-
strokeWidth,
|
|
185
|
-
strokeStyle: dashed ? StrokeStyle.Dash : StrokeStyle.Solid,
|
|
186
|
-
frontEndpointStyle: PointStyle.None,
|
|
187
|
-
rearEndpointStyle: rearArrow ? PointStyle.Arrow : PointStyle.None,
|
|
188
|
-
source: { position: [x1, y1] },
|
|
189
|
-
target: { position: [x2, y2] },
|
|
190
|
-
});
|
|
108
|
+
return surface.addElement(dddConnectorElement({ position: [x1, y1] }, { position: [x2, y2] }, opts));
|
|
191
109
|
}
|
|
192
110
|
/**
|
|
193
111
|
* A Team Topologies interaction-mode marker: a coloured square + centred letter.
|
|
@@ -198,37 +116,11 @@ export function addConnector(surface, x1, y1, x2, y2, opts = {}) {
|
|
|
198
116
|
* passes none keeps producing the neutral drawing it always did.
|
|
199
117
|
*/
|
|
200
118
|
export function addMarker(surface, std, cx, cy, opts) {
|
|
201
|
-
const { fill, letter, label, role } = opts;
|
|
202
119
|
const s = MARKER_SIZE;
|
|
203
|
-
|
|
204
|
-
const glyph = addText(surface, cx - s / 2, cy - 9, s, letter, NOTATION_NEUTRALS.ink, LABEL_FONT, 15);
|
|
205
|
-
const ids = [box, glyph];
|
|
206
|
-
if (label) {
|
|
207
|
-
ids.push(addText(surface, cx + s / 2 + 6, cy - LABEL_FONT_SIZE / 2, 150, label, LABEL_COLOR, LABEL_FONT, LABEL_FONT_SIZE, 'left'));
|
|
208
|
-
}
|
|
209
|
-
return groupIds(std, ids);
|
|
120
|
+
return addElements(surface, std, markerElements({ x: cx - s / 2, y: cy - s / 2 }, opts));
|
|
210
121
|
}
|
|
211
122
|
/** A cloud (Big Ball of Mud / general-purpose boundary): a smoothed closed bezier polygon. */
|
|
212
123
|
export function addCloud(surface, std, cx, cy, label, role) {
|
|
213
|
-
const { w, h
|
|
214
|
-
|
|
215
|
-
type: 'shape',
|
|
216
|
-
shapeType: 'polygon',
|
|
217
|
-
vertices: CLOUD_VERTICES,
|
|
218
|
-
isClosed: true,
|
|
219
|
-
filled: true,
|
|
220
|
-
fillColor: fill,
|
|
221
|
-
strokeColor: stroke,
|
|
222
|
-
strokeWidth: 1.5,
|
|
223
|
-
shapeStyle: ShapeStyle.General,
|
|
224
|
-
roughness: 0,
|
|
225
|
-
xywh: new Bound(cx - w / 2, cy - h / 2, w, h).serialize(),
|
|
226
|
-
// On the POLYGON, never on the group: the polygon is what a relationship
|
|
227
|
-
// binds to and what the legend scan meets.
|
|
228
|
-
...(role ? { role } : {}),
|
|
229
|
-
});
|
|
230
|
-
if (!label)
|
|
231
|
-
return cloud;
|
|
232
|
-
const lbl = addText(surface, cx - w / 2 + 12, cy - LABEL_FONT_SIZE / 2, w - 24, label, NOTATION_NEUTRALS.ink, LABEL_FONT, LABEL_FONT_SIZE);
|
|
233
|
-
return groupIds(std, [cloud, lbl]);
|
|
124
|
+
const { w, h } = CLOUD;
|
|
125
|
+
return addElements(surface, std, cloudElements({ x: cx - w / 2, y: cy - h / 2 }, label, role));
|
|
234
126
|
}
|
package/dist/shared/utils.d.ts
CHANGED
package/dist/shared/utils.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formicoidea/labre-ddd-shared",
|
|
3
3
|
"description": "Labre ddd-shared — shared building blocks for @formicoidea/labre-core frameworks.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.60.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"author": "lajola",
|
|
@@ -13,13 +13,17 @@
|
|
|
13
13
|
".": {
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
15
|
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./headless": {
|
|
18
|
+
"types": "./dist/headless.d.ts",
|
|
19
|
+
"import": "./dist/headless.js"
|
|
16
20
|
}
|
|
17
21
|
},
|
|
18
22
|
"files": [
|
|
19
23
|
"dist"
|
|
20
24
|
],
|
|
21
25
|
"dependencies": {
|
|
22
|
-
"@formicoidea/labre-core": "0.
|
|
26
|
+
"@formicoidea/labre-core": "0.60.0",
|
|
23
27
|
"lit": "^3.2.0",
|
|
24
28
|
"yjs": "^13.6.21"
|
|
25
29
|
}
|