@operato/board 10.28.1 → 10.28.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@operato/board",
3
- "version": "10.28.1",
3
+ "version": "10.28.3",
4
4
  "description": "Webcomponent for board following open-wc recommendations",
5
5
  "author": "heartyoh",
6
6
  "type": "module",
@@ -120,17 +120,17 @@
120
120
  "dependencies": {
121
121
  "@material/web": "^2.0.0",
122
122
  "@open-wc/scoped-elements": "^2.1.3",
123
- "@operato/app": "^10.28.1",
124
- "@operato/data-grist": "^10.27.1",
125
- "@operato/font": "^10.28.0",
126
- "@operato/graphql": "^10.27.1",
123
+ "@operato/app": "^10.28.2",
124
+ "@operato/data-grist": "^10.28.2",
125
+ "@operato/font": "^10.28.2",
126
+ "@operato/graphql": "^10.28.2",
127
127
  "@operato/i18n": "^10.16.2",
128
128
  "@operato/input": "^10.23.0",
129
- "@operato/layout": "^10.28.0",
129
+ "@operato/layout": "^10.28.2",
130
130
  "@operato/markdown": "^10.23.0",
131
131
  "@operato/popup": "^10.23.0",
132
- "@operato/property-editor": "^10.28.0",
133
- "@operato/property-panel": "^10.28.1",
132
+ "@operato/property-editor": "^10.28.2",
133
+ "@operato/property-panel": "^10.28.2",
134
134
  "@operato/styles": "^10.23.0",
135
135
  "@operato/utils": "^10.22.0",
136
136
  "@types/file-saver": "^2.0.4",
@@ -144,7 +144,7 @@
144
144
  "devDependencies": {
145
145
  "@custom-elements-manifest/analyzer": "^0.10.0",
146
146
  "@hatiolab/prettier-config": "^1.0.0",
147
- "@hatiolab/things-scene": "^10.1.26",
147
+ "@hatiolab/things-scene": "^10.1.56",
148
148
  "@open-wc/eslint-config": "^12.0.3",
149
149
  "@open-wc/testing": "^4.0.0",
150
150
  "@rollup/plugin-image": "^3.0.3",
@@ -180,5 +180,5 @@
180
180
  "prettier --write"
181
181
  ]
182
182
  },
183
- "gitHead": "b492992f123490a9f2da325167b40bca9bd0b55f"
183
+ "gitHead": "c1a27d6d383cd8b07449f73242ed0df8a74691fa"
184
184
  }
@@ -1,6 +1,6 @@
1
1
  import { expect } from '@open-wc/testing'
2
2
 
3
- import { Component, hasFigure, hasFigureV3, registerTypeResolver, resetFigures, resetFiguresV3, resolveUnknownTypes } from '@hatiolab/things-scene'
3
+ import { Component, hasFigureV3, registerTypeResolver, resetFiguresV3, resolveUnknownTypes } from '@hatiolab/things-scene'
4
4
 
5
5
  import { createFigureResolver } from '../src/figure-provider.js'
6
6
 
@@ -11,43 +11,12 @@ import { createFigureResolver } from '../src/figure-provider.js'
11
11
  * checked here is the part that belongs to the board: which names are asked about, what happens to
12
12
  * the answer, and how "nobody published this" stays apart from "could not ask".
13
13
  *
14
- * The blueprint below is the shape figure-model emits — `registerFigure` rejects anything it cannot
15
- * read, so a fixture that drifts fails loudly here instead of drawing nothing at runtime.
14
+ * The payload below is written out rather than built with figure-model: this package does not read it, it passes it
15
+ * to the scene's own registration, and a fixture that drifts from the format should fail loudly here rather than
16
+ * draw nothing at runtime.
16
17
  */
17
18
 
18
- const BLUEPRINT_VERSION = 1
19
-
20
- const blueprintOf = (type: string) => ({
21
- version: BLUEPRINT_VERSION,
22
- type,
23
- base: { x: 100, y: 100, z: 100 },
24
- groups: [
25
- {
26
- materialKey: 'palette.dark|metal|f|-|-|-',
27
- material: { token: 'palette.dark', preset: 'metal', flatShading: true },
28
- animated: false,
29
- members: [
30
- {
31
- name: 'body',
32
- primitive: 'cube',
33
- geometryKey: 'cube|100x100x100',
34
- transform: { position: { x: 0, y: 0, z: 0 }, size: { x: 100, y: 100, z: 100 } },
35
- sizing: 'scale',
36
- triangles: 12
37
- }
38
- ]
39
- }
40
- ]
41
- })
42
-
43
- /**
44
- * The other thing the door can hand over: a V3 asset under a `format` tag (ADR-0087 decision 5).
45
- *
46
- * Written out rather than built with figure-model, for the same reason the blueprint above is: this package
47
- * does not read either payload, it passes each to the scene's own registration, and a fixture that drifts from
48
- * the format should fail loudly here rather than draw nothing at runtime. One box standing on the floor, with
49
- * the volume it takes up declared.
50
- */
19
+ /** What the door hands over: a figure asset under a `format` tag. One box standing on the floor, its room declared. */
51
20
  const v3AssetOf = (type: string) => ({
52
21
  version: 'figure-v3-asset-1',
53
22
  name: type,
@@ -100,19 +69,18 @@ function fetcherOf(published: Record<string, unknown>, failing: string[] = []) {
100
69
  if (failing.includes(type)) {
101
70
  throw new Error(`no route to the door (${type})`)
102
71
  }
103
- return published[type] ?? null
72
+ return (published[type] ?? null) as never
104
73
  }
105
74
  }
106
75
  }
107
76
 
108
77
  describe('figure 공급자 — 보드가 발행된 Figure 를 받는 길', () => {
109
78
  afterEach(() => {
110
- resetFigures()
111
79
  resetFiguresV3()
112
80
  })
113
81
 
114
82
  it('대문자 이름만 서버에 묻는다 — 씬의 기본 type 과 오타는 문을 지나지 않는다', async () => {
115
- const { asked, fetch } = fetcherOf({ EQ_MIXER: blueprintOf('EQ_MIXER') })
83
+ const { asked, fetch } = fetcherOf({ EQ_MIXER: v3PayloadOf('EQ_MIXER') })
116
84
 
117
85
  await createFigureResolver(fetch)(['EQ_MIXER', 'rect', 'Conveyor', 'text', 'VEH_AGV_01'])
118
86
 
@@ -120,7 +88,7 @@ describe('figure 공급자 — 보드가 발행된 Figure 를 받는 길', () =>
120
88
  })
121
89
 
122
90
  it('이미 등록된 type 은 묻지 않는다 — 그리고 있는 컴포넌트를 figure 가 덮지 않는다', async () => {
123
- const { asked, fetch } = fetcherOf({ EQ_TAKEN: blueprintOf('EQ_TAKEN') })
91
+ const { asked, fetch } = fetcherOf({ EQ_TAKEN: v3PayloadOf('EQ_TAKEN') })
124
92
 
125
93
  /* Somebody else already draws this name — a plugin, an app's own component. */
126
94
  Component.register('EQ_TAKEN', class Taken extends Component {} as never)
@@ -128,43 +96,48 @@ describe('figure 공급자 — 보드가 발행된 Figure 를 받는 길', () =>
128
96
  await createFigureResolver(fetch)(['EQ_TAKEN'])
129
97
 
130
98
  expect(asked).to.deep.equal([])
131
- expect(hasFigure('EQ_TAKEN')).to.equal(false)
99
+ expect(hasFigureV3('EQ_TAKEN')).to.equal(false)
132
100
  })
133
101
 
134
- it('받은 청사진을 등록한다 — 도면은 type 만 적으면 된다', async () => {
135
- const { fetch } = fetcherOf({ EQ_REGISTERED: blueprintOf('EQ_REGISTERED') })
102
+ it('받은 자산을 등록한다 — 도면은 type 만 적으면 된다', async () => {
103
+ const { fetch } = fetcherOf({ EQ_REGISTERED: v3PayloadOf('EQ_REGISTERED') })
136
104
 
137
105
  await createFigureResolver(fetch)(['EQ_REGISTERED'])
138
106
 
139
- expect(hasFigure('EQ_REGISTERED')).to.equal(true)
107
+ expect(hasFigureV3('EQ_REGISTERED')).to.equal(true)
140
108
  /* The component type is registered with it — the model writes `type` and nothing else. */
141
109
  expect(Component.register('EQ_REGISTERED')).to.not.equal(undefined)
142
110
  })
143
111
 
144
- it('V3 자산은 V3 문으로 등록한다 — 보드는 그것을 읽지 않고 씬에 넘긴다', async () => {
112
+ it('자산은 씬의 문으로 등록한다 — 보드는 그것을 읽지 않고 씬에 넘긴다', async () => {
145
113
  const { fetch } = fetcherOf({ EQ_V3: v3PayloadOf('EQ_V3') })
146
114
 
147
115
  await createFigureResolver(fetch)(['EQ_V3'])
148
116
 
149
117
  expect(hasFigureV3('EQ_V3')).to.equal(true)
150
- expect(hasFigure('EQ_V3')).to.equal(false)
151
- /* 도면은 판을 모른다 — 두 판 다 type 하나만 적으면 그려진다. */
118
+ /* 도면은 type 하나만 적으면 그려진다. */
152
119
  expect(Component.register('EQ_V3')).to.not.equal(undefined)
153
120
  })
154
121
 
155
- it('한 도면에 두 판이 섞여 있어도 각자의 문으로 들어간다', async () => {
156
- const { fetch } = fetcherOf({ EQ_OLD: blueprintOf('EQ_OLD'), EQ_NEW: v3PayloadOf('EQ_NEW') })
122
+ it('자산이 아닌 것(format 이 v3 가 아닌 답)은 그 type 만 실패로 남는다 — 옛 청사진을 그리지 않는다', async () => {
123
+ const { fetch } = fetcherOf({ EQ_NEW: v3PayloadOf('EQ_NEW'), EQ_OLD: { version: 1, type: 'EQ_OLD', groups: [] } })
157
124
 
158
- await createFigureResolver(fetch)(['EQ_OLD', 'EQ_NEW'])
125
+ let message = ''
126
+ try {
127
+ await createFigureResolver(fetch)(['EQ_NEW', 'EQ_OLD'])
128
+ } catch (error) {
129
+ message = error instanceof Error ? error.message : String(error)
130
+ }
159
131
 
160
- expect(hasFigure('EQ_OLD')).to.equal(true)
132
+ expect(message).to.contain('not a figure asset: EQ_OLD')
161
133
  expect(hasFigureV3('EQ_NEW')).to.equal(true)
134
+ expect(hasFigureV3('EQ_OLD')).to.equal(false)
162
135
  })
163
136
 
164
137
  it('읽을 수 없는 V3 자산은 그 type 만 실패로 남는다', async () => {
165
138
  const broken = v3PayloadOf('EQ_V3_BROKEN')
166
139
  broken.asset.appearance = []
167
- const { fetch } = fetcherOf({ EQ_BESIDE_V3: blueprintOf('EQ_BESIDE_V3'), EQ_V3_BROKEN: broken })
140
+ const { fetch } = fetcherOf({ EQ_BESIDE_V3: v3PayloadOf('EQ_BESIDE_V3'), EQ_V3_BROKEN: broken })
168
141
 
169
142
  let message = ''
170
143
  try {
@@ -174,7 +147,7 @@ describe('figure 공급자 — 보드가 발행된 Figure 를 받는 길', () =>
174
147
  }
175
148
 
176
149
  expect(message).to.contain('EQ_V3_BROKEN')
177
- expect(hasFigure('EQ_BESIDE_V3')).to.equal(true)
150
+ expect(hasFigureV3('EQ_BESIDE_V3')).to.equal(true)
178
151
  expect(hasFigureV3('EQ_V3_BROKEN')).to.equal(false)
179
152
  })
180
153
 
@@ -189,11 +162,11 @@ describe('figure 공급자 — 보드가 발행된 Figure 를 받는 길', () =>
189
162
  }
190
163
 
191
164
  expect(rejected).to.equal(false)
192
- expect(hasFigure('EQ_NOT_PUBLISHED')).to.equal(false)
165
+ expect(hasFigureV3('EQ_NOT_PUBLISHED')).to.equal(false)
193
166
  })
194
167
 
195
168
  it('물을 수 없으면 거절한다. 그때도 답을 받은 것은 등록된다', async () => {
196
- const { fetch } = fetcherOf({ EQ_BESIDE_BROKEN: blueprintOf('EQ_BESIDE_BROKEN') }, ['EQ_BROKEN'])
169
+ const { fetch } = fetcherOf({ EQ_BESIDE_BROKEN: v3PayloadOf('EQ_BESIDE_BROKEN') }, ['EQ_BROKEN'])
197
170
 
198
171
  let message = ''
199
172
  try {
@@ -204,13 +177,13 @@ describe('figure 공급자 — 보드가 발행된 Figure 를 받는 길', () =>
204
177
 
205
178
  expect(message).to.contain('EQ_BROKEN')
206
179
  expect(message).to.not.contain('EQ_BESIDE_BROKEN')
207
- expect(hasFigure('EQ_BESIDE_BROKEN')).to.equal(true)
180
+ expect(hasFigureV3('EQ_BESIDE_BROKEN')).to.equal(true)
208
181
  })
209
182
 
210
- it('읽을 수 없는 청사진은 그 type 만 실패로 남는다 — 다른 type 을 막지 않는다', async () => {
183
+ it('읽을 수 없는 자산은 그 type 만 실패로 남는다 — 다른 type 을 막지 않는다', async () => {
211
184
  const { fetch } = fetcherOf({
212
- EQ_BESIDE_MALFORMED: blueprintOf('EQ_BESIDE_MALFORMED'),
213
- EQ_MALFORMED: { version: BLUEPRINT_VERSION, type: 'EQ_MALFORMED' }
185
+ EQ_BESIDE_MALFORMED: v3PayloadOf('EQ_BESIDE_MALFORMED'),
186
+ EQ_MALFORMED: { format: 'v3', type: 'EQ_MALFORMED', asset: { version: 'figure-v3-asset-1' } }
214
187
  })
215
188
 
216
189
  let message = ''
@@ -221,12 +194,12 @@ describe('figure 공급자 — 보드가 발행된 Figure 를 받는 길', () =>
221
194
  }
222
195
 
223
196
  expect(message).to.contain('EQ_MALFORMED')
224
- expect(hasFigure('EQ_BESIDE_MALFORMED')).to.equal(true)
225
- expect(hasFigure('EQ_MALFORMED')).to.equal(false)
197
+ expect(hasFigureV3('EQ_BESIDE_MALFORMED')).to.equal(true)
198
+ expect(hasFigureV3('EQ_MALFORMED')).to.equal(false)
226
199
  })
227
200
 
228
201
  it('씬의 자리에 앉아 동작한다 — 모델의 모르는 type 이 해석 뒤에 남지 않는다', async () => {
229
- const { fetch } = fetcherOf({ EQ_ON_A_BOARD: blueprintOf('EQ_ON_A_BOARD') })
202
+ const { fetch } = fetcherOf({ EQ_ON_A_BOARD: v3PayloadOf('EQ_ON_A_BOARD') })
230
203
  const takeBack = registerTypeResolver(createFigureResolver(fetch))
231
204
 
232
205
  try {
@@ -242,7 +215,7 @@ describe('figure 공급자 — 보드가 발행된 Figure 를 받는 길', () =>
242
215
 
243
216
  expect(resolution.unresolved).to.deep.equal(['EQ_NEVER_PUBLISHED'])
244
217
  expect(resolution.failed).to.deep.equal([])
245
- expect(hasFigure('EQ_ON_A_BOARD')).to.equal(true)
218
+ expect(hasFigureV3('EQ_ON_A_BOARD')).to.equal(true)
246
219
  } finally {
247
220
  takeBack()
248
221
  }
@@ -2,7 +2,7 @@ import { expect, fixture, html } from '@open-wc/testing'
2
2
  import type { LitElement } from 'lit'
3
3
  import { executeServerCommand } from '@web/test-runner-commands'
4
4
 
5
- import { registerTypeResolver, resetFigures } from '@hatiolab/things-scene'
5
+ import { registerTypeResolver, resetFiguresV3 } from '@hatiolab/things-scene'
6
6
 
7
7
  import { createResolvedScene } from '../src/resolved-scene.js'
8
8
  import '../src/ox-board-preview.js'
@@ -51,7 +51,7 @@ describe('모르는 type 이 없으면 아무에게도 묻지 않는다', () =>
51
51
 
52
52
  afterEach(() => {
53
53
  takeBack()
54
- resetFigures()
54
+ resetFiguresV3()
55
55
  })
56
56
 
57
57
  it('씬의 기본 type 만 있는 보드는 공급자를 부르지 않는다', async () => {
@@ -77,7 +77,7 @@ describe('기다리는 동안 화면이 바뀌면 늦게 온 씬은 들어서지
77
77
 
78
78
  afterEach(() => {
79
79
  takeBack?.()
80
- resetFigures()
80
+ resetFiguresV3()
81
81
  })
82
82
 
83
83
  it('앞의 모델을 풀고 돌아왔을 때 미리보기가 다른 모델을 들고 있으면 그 씬은 버린다', async () => {