@_unit/unit 1.0.7 → 1.0.8

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 (57) hide show
  1. package/build/web.js +1201 -0
  2. package/package.json +1 -1
  3. package/public/_worker.js +294 -103
  4. package/public/_worker.js.map +4 -4
  5. package/public/app/html/index.html +74 -0
  6. package/public/build.json +1 -1
  7. package/public/index.js +297 -103
  8. package/public/index.js.map +4 -4
  9. package/src/API.ts +1 -0
  10. package/src/Class/Graph/index.ts +14 -1
  11. package/src/Class/Graph/interface.ts +7 -0
  12. package/src/Class/Graph/moveSubgraph.ts +25 -25
  13. package/src/client/component.ts +18 -7
  14. package/src/client/extractStyle.ts +161 -0
  15. package/src/client/isTextLike.ts +16 -0
  16. package/src/client/platform/web/api/document.ts +3 -0
  17. package/src/debug/graph/watchGraphInternal.ts +2 -0
  18. package/src/debug/graph/watchGraphSetUnitPinSetIdEvent.ts +39 -0
  19. package/src/docs/concept/README.md +8 -2
  20. package/src/interface.ts +1 -0
  21. package/src/script/build/client.ts +4 -2
  22. package/src/spec/Lazy.ts +10 -2
  23. package/src/spec/util.ts +4 -0
  24. package/src/system/_classes.ts +2 -2
  25. package/src/system/_ids.ts +1 -1
  26. package/src/system/_specs.ts +1 -1
  27. package/src/system/core/unit/MergeInput/spec.json +1 -1
  28. package/src/system/globalComponent.ts +29 -0
  29. package/src/system/platform/api/canvas/AddRect/index.ts +2 -6
  30. package/src/system/platform/api/canvas/ToBlob/index.ts +5 -1
  31. package/src/system/platform/api/media/MediaRecorder/index.ts +6 -0
  32. package/src/system/platform/api/media/RequestPictureInPicture/index.ts +10 -5
  33. package/src/system/platform/api/media/image/{BlobToBitmap → ImageToBitmap}/index.ts +10 -10
  34. package/src/system/platform/api/media/image/{BlobToBitmap → ImageToBitmap}/spec.json +9 -18
  35. package/src/system/platform/component/Iframe/Component.ts +2 -0
  36. package/src/system/platform/component/Inherit/Component.ts +0 -18
  37. package/src/system/platform/component/app/Editor/Component.ts +214 -77
  38. package/src/system/platform/component/app/GUI/Component.ts +19 -4
  39. package/src/system/platform/component/canvas/Canvas/index.ts +2 -2
  40. package/src/system/platform/component/media/Video/index.ts +15 -2
  41. package/src/system/platform/core/SetCurrentTime/spec.json +1 -1
  42. package/src/system/platform/core/SetScale/spec.json +1 -1
  43. package/src/system/platform/core/api/location/LocationQuery/spec.json +1 -1
  44. package/src/system/platform/core/asset/IconNames/spec.json +1 -1
  45. package/src/system/platform/core/canvas/DownloadBlob/spec.json +1 -1
  46. package/src/system/platform/core/component/Charcode/spec.json +1 -1
  47. package/src/system/platform/core/download/DownloadGraph/spec.json +1 -1
  48. package/src/system/platform/core/math/geometry/trigonometry/Hypotenuse/spec.json +1 -1
  49. package/src/system/platform/core/math/power/Pow2/spec.json +1 -1
  50. package/src/system/platform/core/string/RemoveNewLine/spec.json +1 -1
  51. package/src/test/system/core/MergeSort.ts +1 -1
  52. package/src/types/GraphSpec.ts +0 -1
  53. package/src/types/interface/B.ts +3 -1
  54. package/src/types/interface/G.ts +8 -0
  55. package/src/types/interface/async/$G.ts +3 -0
  56. package/src/types/interface/async/AsyncG.ts +10 -0
  57. package/public/metadata.mp4 +0 -0
package/src/API.ts CHANGED
@@ -168,6 +168,7 @@ export type API = {
168
168
  elementFromPoint(x: number, y: number): Element
169
169
  getSelection(): Selection
170
170
  createRange(): Range
171
+ exitPictureInPicture(): Promise<void>
171
172
  MutationObserver: IMutationObserverConstructor
172
173
  PositionObserver: IPositionObserverCostructor
173
174
  ResizeObserver: IResizeObserverConstructor
@@ -118,7 +118,6 @@ import { C, C_EE } from '../../types/interface/C'
118
118
  import { ComponentEvents, Component_ } from '../../types/interface/Component'
119
119
  import { G, G_EE, G_MoveSubgraphIntoArgs } from '../../types/interface/G'
120
120
  import { U } from '../../types/interface/U'
121
- import { weakMerge } from '../../types/weakMerge'
122
121
  import { forEach, insert, remove } from '../../util/array'
123
122
  import { callAll } from '../../util/call/callAll'
124
123
  import {
@@ -4535,6 +4534,20 @@ export class Graph<I = any, O = any>
4535
4534
  )
4536
4535
  }
4537
4536
 
4537
+ setUnitPinSetId(
4538
+ unitId: string,
4539
+ type: IO,
4540
+ pinId: string,
4541
+ newPinId: string,
4542
+ emit: boolean = true
4543
+ ): void {
4544
+ const unit = this.getUnit(unitId) as Graph
4545
+
4546
+ unit.setPinSetId(type, pinId, newPinId)
4547
+
4548
+ emit && this.emit('set_unit_pin_set_id', unitId, type, pinId, newPinId, [])
4549
+ }
4550
+
4538
4551
  public setUnitPinConstant(
4539
4552
  unitId: string,
4540
4553
  type: IO,
@@ -198,6 +198,13 @@ export type GraphSetPinSetFunctionalData = {
198
198
  functional: boolean
199
199
  }
200
200
 
201
+ export type GraphSetUnitPinSetId = {
202
+ unitId: string
203
+ type: IO
204
+ pinId: string
205
+ nextPinId: string
206
+ }
207
+
201
208
  export type GraphSetUnitPinConstant = {
202
209
  unitId: string
203
210
  type: IO
@@ -345,7 +345,7 @@ export function moveLinkPinInto(
345
345
  ignoredUnit: Set<string> = new Set(),
346
346
  reverse: boolean
347
347
  ): void {
348
- if (ignoredUnit.has(unitId)) {
348
+ if (ignoredUnit.has(unitId) && graphId !== unitId) {
349
349
  return
350
350
  }
351
351
 
@@ -571,29 +571,29 @@ export function moveMerge(
571
571
 
572
572
  const pickInput = !isInput && !ignoredUnit.has(unitId)
573
573
 
574
- if ((pickInput && nextInput) || (!pickInput && nextOutput)) {
575
- const {
576
- mergeId: nextMergeId,
577
- pinId: nextPinId,
578
- subPinSpec: nextSubPinSpec,
579
- } = pickInput ? nextInput : nextOutput
574
+ // if ((pickInput && nextInput) || (!pickInput && nextOutput)) {
575
+ const {
576
+ mergeId: nextMergeId,
577
+ pinId: nextPinId,
578
+ subPinSpec: nextSubPinSpec,
579
+ } = (pickInput ? nextInput : nextOutput) ?? {}
580
580
 
581
- moveLinkPinInto(
582
- source,
583
- target,
584
- graphId,
585
- unitId,
586
- type,
587
- pinId,
588
- data,
589
- collapseMap,
590
- nextMergeId,
591
- nextPinId,
592
- null,
593
- ignoredUnit,
594
- reverse
595
- )
596
- }
581
+ moveLinkPinInto(
582
+ source,
583
+ target,
584
+ graphId,
585
+ unitId,
586
+ type,
587
+ pinId,
588
+ data,
589
+ collapseMap,
590
+ nextMergeId,
591
+ nextPinId,
592
+ null,
593
+ ignoredUnit,
594
+ reverse
595
+ )
596
+ // }
597
597
  }
598
598
 
599
599
  forEachPinOnMerge(mergeSpec, moveMergePin)
@@ -981,7 +981,7 @@ export function movePlug(
981
981
  subPinId
982
982
  )
983
983
 
984
- const nextSubPinSpec = pathOrDefault(
984
+ const nextSubPinSpec: GraphSubPinSpec = pathOrDefault(
985
985
  nextPlugSpec,
986
986
  [type, pinId, subPinId],
987
987
  undefined
@@ -1004,7 +1004,7 @@ export function movePlug(
1004
1004
  return
1005
1005
  }
1006
1006
 
1007
- const { nextPinId } = nextSubPinSpec
1007
+ const { pinId: nextPinId = subPinSpec.pinId } = nextSubPinSpec
1008
1008
 
1009
1009
  let nextSubPinSpec_ = nextSubPinSpec
1010
1010
 
@@ -1042,19 +1042,14 @@ export class Component<
1042
1042
  return getRect(this.$element)
1043
1043
  }
1044
1044
 
1045
- getBoundingClientRect(): {
1046
- x: number
1047
- y: number
1048
- width: number
1049
- height: number
1050
- } {
1045
+ getBoundingClientRect(): Rect {
1051
1046
  if (this.$context) {
1052
1047
  if (!this.$primitive) {
1053
1048
  throw new Error('cannot calculate position of multiple elements.')
1054
1049
  }
1055
1050
 
1056
1051
  if (this.$element instanceof Text) {
1057
- // RETURN
1052
+ // TODO
1058
1053
  return
1059
1054
  }
1060
1055
 
@@ -1958,6 +1953,22 @@ export class Component<
1958
1953
  }
1959
1954
  }
1960
1955
 
1956
+ async requestPictureInPicture(): Promise<void> {
1957
+ const {
1958
+ api: {
1959
+ document: { requestPictureInPictureWindow },
1960
+ },
1961
+ } = this.$system
1962
+
1963
+ const pipWindow = await requestPictureInPictureWindow()
1964
+
1965
+ // @ts-ignore
1966
+ if (pipWindow.document) {
1967
+ // @ts-ignore
1968
+ pipWindow.document.body.appendChild(this.$element)
1969
+ }
1970
+ }
1971
+
1961
1972
  public insertParentChildAt(
1962
1973
  component: Component,
1963
1974
  slotName: string,
@@ -5,6 +5,7 @@ import { Component } from './component'
5
5
  import { DEFAULT_FONT_SIZE } from './DEFAULT_FONT_SIZE'
6
6
  import { extractTrait } from './extractTrait'
7
7
  import { IOElement } from './IOElement'
8
+ import { isContentEditable } from './isTextLike'
8
9
  import { LayoutNode } from './LayoutNode'
9
10
  import { rawExtractStyle } from './rawExtractStyle'
10
11
  import { expandSlot } from './reflectComponentBaseTrait'
@@ -307,3 +308,163 @@ export function _extractStyle(
307
308
 
308
309
  return style
309
310
  }
311
+
312
+ export function extractFromRawStyle(
313
+ root: Component,
314
+ component: Component,
315
+ element: IOElement,
316
+ style: Style,
317
+ fallbackTrait: LayoutNode,
318
+ measureText: (text: string, fontSize: number) => Size,
319
+ fitContent: boolean = false,
320
+ getLeafStyle: (
321
+ parent_trait: LayoutNode,
322
+ leaf_path: string[],
323
+ leaf_comp: Component
324
+ ) => Style = (parent_trait, leaf_path, leaf_comp) =>
325
+ extractStyle(root, leaf_comp, parent_trait, measureText, fitContent)
326
+ ): Style {
327
+ const fitWidth = style['width'] === 'fit-content'
328
+ const fitHeight = style['height'] === 'fit-content'
329
+
330
+ if (element instanceof Text) {
331
+ const fontSize = component.getFontSize()
332
+
333
+ const { textContent } = component.$element
334
+
335
+ const { width, height } = measureText(textContent, fontSize)
336
+
337
+ return {
338
+ width: `${width}px`,
339
+ height: `${height}px`,
340
+ }
341
+ }
342
+
343
+ if (isContentEditable(element) && (fitWidth || fitHeight)) {
344
+ const fontSize = component.getFontSize()
345
+
346
+ const { textContent } = component.$element
347
+
348
+ const { width, height } = measureText(textContent, fontSize)
349
+
350
+ if (fitWidth) {
351
+ style['width'] = `${width}px`
352
+ }
353
+
354
+ if (fitHeight) {
355
+ style['height'] = `${height}px`
356
+ }
357
+ }
358
+
359
+ if (style['display'] === 'contents') {
360
+ return {
361
+ width: '100%',
362
+ height: '100%',
363
+ }
364
+ }
365
+
366
+ if (element instanceof HTMLCanvasElement) {
367
+ const treatProp = (name: 'width' | 'height') => {
368
+ const prop = component.getProp(name)
369
+
370
+ if (prop !== undefined) {
371
+ if (typeof prop === 'string') {
372
+ if (isFrameRelativeValue(prop)) {
373
+ const prop_num = prop.substring(0, prop.length - 2)
374
+
375
+ style[name] = `${prop_num}%`
376
+ } else {
377
+ // TODO
378
+ }
379
+ } else {
380
+ style[name] = `${prop}px`
381
+ }
382
+ } else {
383
+ style[name] = `${element[name]}px`
384
+ }
385
+ }
386
+
387
+ treatProp('width')
388
+ treatProp('height')
389
+ }
390
+
391
+ if (element instanceof HTMLInputElement) {
392
+ if (
393
+ element.type === 'text' ||
394
+ element.type === 'number' ||
395
+ element.type === 'password'
396
+ ) {
397
+ if (style.height === 'fit-content') {
398
+ const { value } = element
399
+
400
+ const fontSize = element.style.fontSize
401
+
402
+ const fontSizeNum = parseFontSize(fontSize) ?? DEFAULT_FONT_SIZE
403
+
404
+ const { height } = measureText(value, fontSizeNum)
405
+
406
+ style.height = `${height}px`
407
+ }
408
+ }
409
+
410
+ if (element.type === 'range') {
411
+ style.height = '18px'
412
+ }
413
+ } else if (element instanceof HTMLSelectElement) {
414
+ style.height = '18px'
415
+ }
416
+
417
+ if (element instanceof SVGPathElement) {
418
+ const d = element.getAttribute('d')
419
+
420
+ const bb = getPathBoundingBox(d)
421
+
422
+ style['width'] = `${bb.width}px`
423
+ style['height'] = `${bb.height}px`
424
+
425
+ // TODO
426
+ }
427
+
428
+ if (element instanceof SVGRectElement) {
429
+ style['width'] = `${element.width.animVal.value}px`
430
+ style['height'] = `${element.height.animVal.value}px`
431
+
432
+ // TODO
433
+ }
434
+
435
+ if (element instanceof SVGCircleElement) {
436
+ const r = element.r.animVal.value
437
+
438
+ const width = 2 * r
439
+ const height = width
440
+
441
+ style['width'] = `${width}px`
442
+ style['height'] = `${height}px`
443
+
444
+ // TODO
445
+ }
446
+
447
+ if (fitContent) {
448
+ if (fitWidth || fitHeight) {
449
+ const { width, height } = measureChildren(
450
+ root,
451
+ component,
452
+ style,
453
+ fallbackTrait,
454
+ measureText,
455
+ fitContent,
456
+ getLeafStyle
457
+ )
458
+
459
+ if (fitWidth) {
460
+ style['width'] = `${width}px`
461
+ }
462
+
463
+ if (fitHeight) {
464
+ style['height'] = `${height}px`
465
+ }
466
+ }
467
+ }
468
+
469
+ return style
470
+ }
@@ -0,0 +1,16 @@
1
+ import { IOElement } from './IOElement'
2
+ import { Component } from './component'
3
+
4
+ export function isTextLike(leaf_comp: Component): boolean {
5
+ const is_text =
6
+ leaf_comp.$element instanceof Text || isContentEditable(leaf_comp.$element)
7
+
8
+ return is_text
9
+ }
10
+
11
+ export function isContentEditable(element: IOElement): boolean {
12
+ return (
13
+ element instanceof HTMLDivElement &&
14
+ element.getAttribute('contenteditable') === 'true'
15
+ )
16
+ }
@@ -45,6 +45,9 @@ export function webDocument(
45
45
  createRange(): Range {
46
46
  return document.createRange()
47
47
  },
48
+ exitPictureInPicture(): Promise<void> {
49
+ return document.exitPictureInPicture()
50
+ },
48
51
  MutationObserver: MutationObserver,
49
52
  ResizeObserver: ResizeObserver,
50
53
  PositionObserver: PositionObserver,
@@ -21,6 +21,7 @@ import { watchGraphSetUnitIdEvent } from './watchGraphSetUnitIdEvent'
21
21
  import { watchGraphSetUnitPinConstant } from './watchGraphSetUnitPinConstantEvent'
22
22
  import { watchGraphSetUnitPinData } from './watchGraphSetUnitPinDataEvent'
23
23
  import { watchGraphSetUnitPinIgnored } from './watchGraphSetUnitPinIgnoredEvent'
24
+ import { watchGraphSetUnitPinSetId } from './watchGraphSetUnitPinSetIdEvent'
24
25
  import { watchGraphUnitComponentAppendEvent } from './watchGraphUnitComponentAppendEvent'
25
26
  import { watchGraphUnitComponentRemoveEvent } from './watchGraphUnitComponentRemoveEvent'
26
27
  import {
@@ -54,6 +55,7 @@ export const GRAPH_EVENT_TO_WATCHER: Dict<
54
55
  reorder_sub_component: watchGraphReorderSubComponent,
55
56
  move_sub_component_root: watchGraphMoveSubComponentRoot,
56
57
  set_unit_pin_constant: watchGraphSetUnitPinConstant,
58
+ set_unit_pin_set_id: watchGraphSetUnitPinSetId,
57
59
  set_unit_pin_ignored: watchGraphSetUnitPinIgnored,
58
60
  set_pin_set_functional: watchGraphSetUnitPinFunctional,
59
61
  set_pin_set_id: watchGraphSetPinSetId,
@@ -0,0 +1,39 @@
1
+ import { Graph } from '../../Class/Graph'
2
+ import { GraphSetUnitPinSetId } from '../../Class/Graph/interface'
3
+ import { G_EE } from '../../types/interface/G'
4
+ import { Moment } from '../Moment'
5
+
6
+ export interface GraphSetUnitPinSetIdMomentData extends GraphSetUnitPinSetId {
7
+ path: string[]
8
+ }
9
+
10
+ export interface GraphSetUnitPinSetIdMoment
11
+ extends Moment<GraphSetUnitPinSetIdMomentData> {}
12
+
13
+ export function watchGraphSetUnitPinSetId(
14
+ event: 'set_unit_pin_set_id',
15
+ graph: Graph,
16
+ callback: (moment: GraphSetUnitPinSetIdMoment) => void
17
+ ): () => void {
18
+ const listener = (
19
+ ...[unitId, type, pinId, nextPinId, path]: G_EE['set_unit_pin_set_id']
20
+ ) => {
21
+ callback({
22
+ type: 'graph',
23
+ event,
24
+ data: {
25
+ unitId,
26
+ type,
27
+ pinId,
28
+ nextPinId,
29
+ path,
30
+ },
31
+ })
32
+ }
33
+
34
+ graph.prependListener(event, listener)
35
+
36
+ return () => {
37
+ graph.removeListener(event, listener)
38
+ }
39
+ }
@@ -12,7 +12,7 @@ Unit is also heavily inspired by Functional and Reactive Programming, both highl
12
12
 
13
13
  The Unit paradigm was specially designed to enable easy visual creation of programs called units, which can be interacted with through their inputs and outputs. A new unit can be built by piping and collapsing together smaller units, in a process called Composition. Unit's fundamentals are not new by themselves - in fact, Unit represents a purposeful re-exploration of Computer Science principles in the context of modern Software Development.
14
14
 
15
- The simplicity of Programming in Unit comes from the iterative application of a very small set of principles. One may start out with an initial set of units, which can be linked together forming a new graph unit, in a process called Composition. Symmetrically, a graph can be decomposed and disconnected into its set of smaller units. Moreover any software can be built by repeatedly taping into those.
15
+ The simplicity of Programming in Unit comes from the iterative application of a very small set of principles. One may start out with an initial set of units, which can be linked together forming a new graph unit, in a process called Composition. Symmetrically, a graph can be decomposed and disconnected into its set of smaller units. Moreover any software can be built by repeating this process.
16
16
 
17
17
  The concept of a Unit is essentially an advancement of the fundamental concept of a function, common to many Textual Programming Languages, such as JavaScript and C++. A function is supposed to be given an ordered list of arguments as input and it can return a single datum as output. A unit, on the other hand, can receive and send data at any time, in any order and through multiple inputs and outputs. We believe that redefining the fundamental building block of Programming as a unit can exponentially reduce Software Complexity.
18
18
 
@@ -30,6 +30,12 @@ That brings us to the world of User Interfaces (UI), which is inseparable from t
30
30
 
31
31
  Today, programming a UI is about building a thin visual layer on top of a thick black box, represented by the figure of an "app". Such apps are usually optimized, in logic and design, for a specific set of use cases, invariably rendering the UI either unfit or overfit for real life use cases, which are often unpredictable; the user is not free to arbitrarily mold the interface to his liking. He can neither extend nor extract nor focus on the objects he is currently interested on, so he's forced to content with the lack or interference of a certain UI element. This renders people hostage to the specific design decisions of many one-size-fits-all apps, which are usually borderline impossible to customize or extend.
32
32
 
33
- In Unit, the (visual) components that make up a user interface are units! That means they can be composed and decomposed on will. The user can always inspect the layout and logic of anything he can put his eyes on, being that copying, extending, changing or removing. Therefore, like any other unit, every unit website can be unwrapped into its subcomponents, which live side by side with the logical circuitry that controls them; no context switch between Design and Development.
33
+ In Unit, the (visual) components that make up a user interface are units! That means they can be composed and decomposed on will. The user can always inspect the layout and logic of anything he can put his eyes on, being that copying, extending, changing or removing. Therefore, like any other unit, every unit website can be unwrapped into its subcomponents, which live side by side with the logical circuitry that controls them - no context switch between Design and Development.
34
+
35
+ Likewise, in Unit, there is no explicit separation between "frontend" and "backend". All unit processes can contain components, which helps to visualize it, and can be accessed through an array of standard communication channels. Therefore, the Unit programmer is able to debug "client" and "server" logic side by side. More practically, this divide comes down to the presence of centain APIs, such as "HTTP", "File System" and "Database", which are available in Unit regardless of the host system, so the same program can run anywhere seamlessly regardless of the underlying system/engine.
36
+
37
+ Curiously, the Unit Environment is optimized for the case of 0 code. It can be used as day to day system, where the user practices no direct programming at all. The user starts out with an empty infinite canvas that can be conveniently populated with the desired units to build up the user's own personal spaces, some ephemeral, most reusable.
38
+
39
+ There's a curious emergent pattern here: Unit evolves by removing the auto-imposed divide between concepts that can otherwise work very well together: "user" and "programmer", "developer" and "designer", "client" and "server", "local" and "remote", "sync" and "async", "apps" and "systems".
34
40
 
35
41
  Unit shifts the software paradigm in the direction of user empowerment.
package/src/interface.ts CHANGED
@@ -50,6 +50,7 @@ export const INHERITANCE = {
50
50
  CH: ['EE'],
51
51
  IB: ['I'],
52
52
  W: ['EE', 'CH'],
53
+ B: ['IM'],
53
54
  }
54
55
 
55
56
  export type AllTypes<T> = {
@@ -1,4 +1,4 @@
1
- import { writeFileSync } from 'fs'
1
+ import { copy, writeFile } from 'fs-extra'
2
2
  import { build } from '../build'
3
3
  ;(async () => {
4
4
  const result = await build({
@@ -14,7 +14,9 @@ import { build } from '../build'
14
14
  metafile: true,
15
15
  })
16
16
 
17
- writeFileSync('public/build.json', JSON.stringify(result.metafile ?? {}))
17
+ await writeFile('public/build.json', JSON.stringify(result.metafile ?? {}))
18
+
19
+ await copy('public/index.js', 'build/web.js')
18
20
  })()
19
21
 
20
22
  export default null
package/src/spec/Lazy.ts CHANGED
@@ -53,8 +53,7 @@ export function lazyFromSpec(
53
53
 
54
54
  public __ = ['U', 'G']
55
55
 
56
- public stateful: boolean = false // RETURN __stateful
57
- public __element: boolean = false // RETURN __element
56
+ public __element: boolean = false
58
57
 
59
58
  private __graph: Graph
60
59
 
@@ -104,6 +103,15 @@ export function lazyFromSpec(
104
103
  }
105
104
  })
106
105
  }
106
+ setUnitPinSetId(
107
+ unitId: string,
108
+ type: IO,
109
+ pinId: string,
110
+ newPinId: string,
111
+ ...extra: any[]
112
+ ): void {
113
+ throw new Error('Method not implemented.')
114
+ }
107
115
 
108
116
  fork(): void {
109
117
  this._ensure()
package/src/spec/util.ts CHANGED
@@ -98,6 +98,10 @@ export const getExposedPinSpecs = (graph: GraphSpec) => {
98
98
  }
99
99
  }
100
100
 
101
+ export const getExposePinSpec = (graph: GraphSpec, type: IO, pinId: string) => {
102
+ return pathOrDefault(graph, [`${type}s`, pinId], undefined)
103
+ }
104
+
101
105
  export const getUnitExposedPins = (
102
106
  graph: GraphSpec,
103
107
  unitId: string
@@ -183,7 +183,7 @@ import EnumerateDevices from './platform/api/media/EnumerateDevices'
183
183
  import GetDisplayMedia from './platform/api/media/GetDisplayMedia'
184
184
  import GetVideoTracks from './platform/api/media/GetVideoTracks'
185
185
  import GrabFrame from './platform/api/media/GrabFrame'
186
- import BlobToBitmap from './platform/api/media/image/BlobToBitmap'
186
+ import ImageToBitmap from './platform/api/media/image/ImageToBitmap'
187
187
  import ImageCapture from './platform/api/media/ImageCapture'
188
188
  import MediaRecorder from './platform/api/media/MediaRecorder'
189
189
  import RequestPictureInPicture from './platform/api/media/RequestPictureInPicture'
@@ -510,7 +510,7 @@ export default {
510
510
  '6705462c-5b47-11eb-9dfc-2f14c58b2789': GetDisplayMedia,
511
511
  '0bc0c4ad-d2e0-4e3e-92e8-5b9dfee1cf5e': GetVideoTracks,
512
512
  'f238caff-3f71-40d9-b1a9-d992060fea04': GrabFrame,
513
- '262beb5f-21bd-4848-a62d-185f6f8a78e1': BlobToBitmap,
513
+ '262beb5f-21bd-4848-a62d-185f6f8a78e1': ImageToBitmap,
514
514
  'a57383a9-5b24-4dbb-a5d1-0e278d036f89': ImageCapture,
515
515
  '7e1b3a4c-be6b-11eb-b098-1b6b9db93f1e': MediaRecorder,
516
516
  '3889d2f1-a0ed-4e8c-8e75-7a6683224275': RequestPictureInPicture,
@@ -386,7 +386,7 @@ export const ID_ENUMERATE_DEVICES = '3511f756-2a02-4346-b417-8c34502f79d4'
386
386
  export const ID_GET_DISPLAY_MEDIA = '6705462c-5b47-11eb-9dfc-2f14c58b2789'
387
387
  export const ID_GET_VIDEO_TRACKS = '0bc0c4ad-d2e0-4e3e-92e8-5b9dfee1cf5e'
388
388
  export const ID_GRAB_FRAME = 'f238caff-3f71-40d9-b1a9-d992060fea04'
389
- export const ID_BLOB_TO_BITMAP = '262beb5f-21bd-4848-a62d-185f6f8a78e1'
389
+ export const ID_IMAGE_TO_BITMAP = '262beb5f-21bd-4848-a62d-185f6f8a78e1'
390
390
  export const ID_IMAGE_CAPTURE = 'a57383a9-5b24-4dbb-a5d1-0e278d036f89'
391
391
  export const ID_MEDIA_RECORDER = '7e1b3a4c-be6b-11eb-b098-1b6b9db93f1e'
392
392
  export const ID_REQUEST_PICTURE_IN_PICTURE = '3889d2f1-a0ed-4e8c-8e75-7a6683224275'