@e280/quay 0.0.0-1

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 (206) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +117 -0
  3. package/package.json +57 -0
  4. package/s/cellar/cask.ts +18 -0
  5. package/s/cellar/cellar.test.ts +100 -0
  6. package/s/cellar/cellar.ts +53 -0
  7. package/s/cellar/forklift.ts +9 -0
  8. package/s/cellar/index.ts +7 -0
  9. package/s/cellar/memory-forklift.ts +29 -0
  10. package/s/cellar/opfs-forklift.ts +49 -0
  11. package/s/demo/main.bundle.ts +39 -0
  12. package/s/demo/main.css +126 -0
  13. package/s/dom/components/breadcrumb/component.ts +29 -0
  14. package/s/dom/components/browser/component.ts +75 -0
  15. package/s/dom/components/browser/style.css.ts +118 -0
  16. package/s/dom/components/dropzone/component.ts +33 -0
  17. package/s/dom/components/dropzone/style.css.ts +54 -0
  18. package/s/dom/components/filter/component.ts +44 -0
  19. package/s/dom/components/outliner/component.ts +16 -0
  20. package/s/dom/components/searchbar/component.ts +29 -0
  21. package/s/dom/components/sort/component.ts +48 -0
  22. package/s/dom/components.ts +15 -0
  23. package/s/dom/context.ts +5 -0
  24. package/s/dom/theme.css.ts +11 -0
  25. package/s/dom/utils/find-group-name.ts +12 -0
  26. package/s/dom/utils/find-local-group.ts +9 -0
  27. package/s/dom/views/tree/component.ts +64 -0
  28. package/s/dom/views/tree/style.css.ts +64 -0
  29. package/s/genius/folio.md +29 -0
  30. package/s/genius/parts/hy-tree.ts +142 -0
  31. package/s/genius/quay.md +13 -0
  32. package/s/genius/turbo.md +21 -0
  33. package/s/genius/twig.ts +34 -0
  34. package/s/index.html.ts +89 -0
  35. package/s/index.ts +14 -0
  36. package/s/logic/aspects/codex/codex.ts +46 -0
  37. package/s/logic/aspects/codex/example.ts +65 -0
  38. package/s/logic/aspects/codex/parts/clade.ts +28 -0
  39. package/s/logic/aspects/codex/parts/codex-item.ts +94 -0
  40. package/s/logic/aspects/codex/parts/hierarchy.ts +82 -0
  41. package/s/logic/aspects/codex/parts/taxonomy.ts +18 -0
  42. package/s/logic/aspects/codex/parts/types.ts +23 -0
  43. package/s/logic/aspects/codex/utils/generate-id.ts +7 -0
  44. package/s/logic/aspects/dropzone.ts +77 -0
  45. package/s/logic/aspects/tree-trail.ts +33 -0
  46. package/s/logic/brain.ts +22 -0
  47. package/s/logic/group.ts +104 -0
  48. package/s/logic/permissions.ts +34 -0
  49. package/s/logic/presets/media/group.ts +94 -0
  50. package/s/logic/presets/media/schema.ts +22 -0
  51. package/s/logic/presets/opfs/schema.ts +21 -0
  52. package/s/logic/presets/plain/group.ts +44 -0
  53. package/s/logic/presets/plain/schema.ts +15 -0
  54. package/s/logic/types.ts +33 -0
  55. package/s/tests.test.ts +8 -0
  56. package/x/cellar/cask.d.ts +8 -0
  57. package/x/cellar/cask.js +19 -0
  58. package/x/cellar/cask.js.map +1 -0
  59. package/x/cellar/cellar.d.ts +22 -0
  60. package/x/cellar/cellar.js +47 -0
  61. package/x/cellar/cellar.js.map +1 -0
  62. package/x/cellar/cellar.test.d.ts +11 -0
  63. package/x/cellar/cellar.test.js +79 -0
  64. package/x/cellar/cellar.test.js.map +1 -0
  65. package/x/cellar/forklift.d.ts +7 -0
  66. package/x/cellar/forklift.js +2 -0
  67. package/x/cellar/forklift.js.map +1 -0
  68. package/x/cellar/index.d.ts +5 -0
  69. package/x/cellar/index.js +6 -0
  70. package/x/cellar/index.js.map +1 -0
  71. package/x/cellar/memory-forklift.d.ts +9 -0
  72. package/x/cellar/memory-forklift.js +21 -0
  73. package/x/cellar/memory-forklift.js.map +1 -0
  74. package/x/cellar/opfs-forklift.d.ts +11 -0
  75. package/x/cellar/opfs-forklift.js +44 -0
  76. package/x/cellar/opfs-forklift.js.map +1 -0
  77. package/x/demo/main.bundle.d.ts +1 -0
  78. package/x/demo/main.bundle.js +30 -0
  79. package/x/demo/main.bundle.js.map +1 -0
  80. package/x/demo/main.bundle.min.js +471 -0
  81. package/x/demo/main.css +126 -0
  82. package/x/dom/components/breadcrumb/component.d.ts +1 -0
  83. package/x/dom/components/breadcrumb/component.js +21 -0
  84. package/x/dom/components/breadcrumb/component.js.map +1 -0
  85. package/x/dom/components/browser/component.d.ts +1 -0
  86. package/x/dom/components/browser/component.js +65 -0
  87. package/x/dom/components/browser/component.js.map +1 -0
  88. package/x/dom/components/browser/style.css.d.ts +2 -0
  89. package/x/dom/components/browser/style.css.js +117 -0
  90. package/x/dom/components/browser/style.css.js.map +1 -0
  91. package/x/dom/components/dropzone/component.d.ts +1 -0
  92. package/x/dom/components/dropzone/component.js +27 -0
  93. package/x/dom/components/dropzone/component.js.map +1 -0
  94. package/x/dom/components/dropzone/style.css.d.ts +2 -0
  95. package/x/dom/components/dropzone/style.css.js +53 -0
  96. package/x/dom/components/dropzone/style.css.js.map +1 -0
  97. package/x/dom/components/filter/component.d.ts +1 -0
  98. package/x/dom/components/filter/component.js +40 -0
  99. package/x/dom/components/filter/component.js.map +1 -0
  100. package/x/dom/components/outliner/component.d.ts +1 -0
  101. package/x/dom/components/outliner/component.js +13 -0
  102. package/x/dom/components/outliner/component.js.map +1 -0
  103. package/x/dom/components/searchbar/component.d.ts +1 -0
  104. package/x/dom/components/searchbar/component.js +24 -0
  105. package/x/dom/components/searchbar/component.js.map +1 -0
  106. package/x/dom/components/sort/component.d.ts +1 -0
  107. package/x/dom/components/sort/component.js +44 -0
  108. package/x/dom/components/sort/component.js.map +1 -0
  109. package/x/dom/components.d.ts +18 -0
  110. package/x/dom/components.js +13 -0
  111. package/x/dom/components.js.map +1 -0
  112. package/x/dom/context.d.ts +2 -0
  113. package/x/dom/context.js +3 -0
  114. package/x/dom/context.js.map +1 -0
  115. package/x/dom/theme.css.d.ts +2 -0
  116. package/x/dom/theme.css.js +11 -0
  117. package/x/dom/theme.css.js.map +1 -0
  118. package/x/dom/utils/find-group-name.d.ts +1 -0
  119. package/x/dom/utils/find-group-name.js +9 -0
  120. package/x/dom/utils/find-group-name.js.map +1 -0
  121. package/x/dom/utils/find-local-group.d.ts +1 -0
  122. package/x/dom/utils/find-local-group.js +7 -0
  123. package/x/dom/utils/find-local-group.js.map +1 -0
  124. package/x/dom/views/tree/component.d.ts +7 -0
  125. package/x/dom/views/tree/component.js +52 -0
  126. package/x/dom/views/tree/component.js.map +1 -0
  127. package/x/dom/views/tree/style.css.d.ts +2 -0
  128. package/x/dom/views/tree/style.css.js +63 -0
  129. package/x/dom/views/tree/style.css.js.map +1 -0
  130. package/x/genius/folio.md +29 -0
  131. package/x/genius/parts/hy-tree.d.ts +44 -0
  132. package/x/genius/parts/hy-tree.js +116 -0
  133. package/x/genius/parts/hy-tree.js.map +1 -0
  134. package/x/genius/quay.md +13 -0
  135. package/x/genius/turbo.md +21 -0
  136. package/x/genius/twig.d.ts +34 -0
  137. package/x/genius/twig.js +2 -0
  138. package/x/genius/twig.js.map +1 -0
  139. package/x/importmap.json +47 -0
  140. package/x/index.d.ts +11 -0
  141. package/x/index.html +170 -0
  142. package/x/index.html.d.ts +3 -0
  143. package/x/index.html.js +87 -0
  144. package/x/index.html.js.map +1 -0
  145. package/x/index.js +9 -0
  146. package/x/index.js.map +1 -0
  147. package/x/logic/aspects/codex/codex.d.ts +17 -0
  148. package/x/logic/aspects/codex/codex.js +39 -0
  149. package/x/logic/aspects/codex/codex.js.map +1 -0
  150. package/x/logic/aspects/codex/example.d.ts +13 -0
  151. package/x/logic/aspects/codex/example.js +42 -0
  152. package/x/logic/aspects/codex/example.js.map +1 -0
  153. package/x/logic/aspects/codex/parts/clade.d.ts +16 -0
  154. package/x/logic/aspects/codex/parts/clade.js +23 -0
  155. package/x/logic/aspects/codex/parts/clade.js.map +1 -0
  156. package/x/logic/aspects/codex/parts/codex-item.d.ts +33 -0
  157. package/x/logic/aspects/codex/parts/codex-item.js +74 -0
  158. package/x/logic/aspects/codex/parts/codex-item.js.map +1 -0
  159. package/x/logic/aspects/codex/parts/hierarchy.d.ts +23 -0
  160. package/x/logic/aspects/codex/parts/hierarchy.js +69 -0
  161. package/x/logic/aspects/codex/parts/hierarchy.js.map +1 -0
  162. package/x/logic/aspects/codex/parts/taxonomy.d.ts +7 -0
  163. package/x/logic/aspects/codex/parts/taxonomy.js +13 -0
  164. package/x/logic/aspects/codex/parts/taxonomy.js.map +1 -0
  165. package/x/logic/aspects/codex/parts/types.d.ts +22 -0
  166. package/x/logic/aspects/codex/parts/types.js +2 -0
  167. package/x/logic/aspects/codex/parts/types.js.map +1 -0
  168. package/x/logic/aspects/codex/utils/generate-id.d.ts +1 -0
  169. package/x/logic/aspects/codex/utils/generate-id.js +5 -0
  170. package/x/logic/aspects/codex/utils/generate-id.js.map +1 -0
  171. package/x/logic/aspects/dropzone.d.ts +16 -0
  172. package/x/logic/aspects/dropzone.js +60 -0
  173. package/x/logic/aspects/dropzone.js.map +1 -0
  174. package/x/logic/aspects/tree-trail.d.ts +8 -0
  175. package/x/logic/aspects/tree-trail.js +24 -0
  176. package/x/logic/aspects/tree-trail.js.map +1 -0
  177. package/x/logic/brain.d.ts +11 -0
  178. package/x/logic/brain.js +17 -0
  179. package/x/logic/brain.js.map +1 -0
  180. package/x/logic/group.d.ts +51 -0
  181. package/x/logic/group.js +79 -0
  182. package/x/logic/group.js.map +1 -0
  183. package/x/logic/permissions.d.ts +18 -0
  184. package/x/logic/permissions.js +26 -0
  185. package/x/logic/permissions.js.map +1 -0
  186. package/x/logic/presets/media/group.d.ts +7 -0
  187. package/x/logic/presets/media/group.js +75 -0
  188. package/x/logic/presets/media/group.js.map +1 -0
  189. package/x/logic/presets/media/schema.d.ts +18 -0
  190. package/x/logic/presets/media/schema.js +2 -0
  191. package/x/logic/presets/media/schema.js.map +1 -0
  192. package/x/logic/presets/opfs/schema.d.ts +18 -0
  193. package/x/logic/presets/opfs/schema.js +2 -0
  194. package/x/logic/presets/opfs/schema.js.map +1 -0
  195. package/x/logic/presets/plain/group.d.ts +7 -0
  196. package/x/logic/presets/plain/group.js +33 -0
  197. package/x/logic/presets/plain/group.js.map +1 -0
  198. package/x/logic/presets/plain/schema.d.ts +12 -0
  199. package/x/logic/presets/plain/schema.js +2 -0
  200. package/x/logic/presets/plain/schema.js.map +1 -0
  201. package/x/logic/types.d.ts +20 -0
  202. package/x/logic/types.js +11 -0
  203. package/x/logic/types.js.map +1 -0
  204. package/x/tests.test.d.ts +1 -0
  205. package/x/tests.test.js +6 -0
  206. package/x/tests.test.js.map +1 -0
package/x/index.html ADDED
@@ -0,0 +1,170 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1"/>
6
+
7
+ <meta name="darkreader-lock"/>
8
+
9
+ <title>Quay</title>
10
+ <link rel="stylesheet" href="demo/main.css?v=c15dc8e4"/>
11
+
12
+ <link rel="icon" href="/assets/favicon.png"/>
13
+ <meta data-commit-hash="9fb8a817cffeeb58d88f33f7da881ae2fe28260b"/>
14
+
15
+
16
+ <meta name="theme-color" content="#eb6f1d">
17
+
18
+ <meta property="og:type" content="website">
19
+ <meta property="og:site_name" content="quay.e280.org">
20
+ <meta property="og:title" content="Quay — File-browser UI Framework">
21
+ <meta property="og:description" content="Customizable outliner web ui toolkit for nested things">
22
+ <meta property="og:image" content="https://quay.e280.org/assets/favicon.png">
23
+ <meta property="og:url" content="https://quay.e280.org/">
24
+
25
+
26
+
27
+
28
+
29
+ <script type="importmap">
30
+ {
31
+ "imports": {
32
+ "@benev/slate/": "/node_modules/@benev/slate/",
33
+ "@benev/slate": "/node_modules/@benev/slate/x/index.js",
34
+ "@e280/kv/": "/node_modules/@e280/kv/",
35
+ "@e280/kv": "/node_modules/@e280/kv/x/index.js",
36
+ "@e280/stz/": "/node_modules/@e280/stz/",
37
+ "@e280/stz": "/node_modules/@e280/stz/x/index.js",
38
+ "@lit-labs/ssr-dom-shim/": "/node_modules/@lit-labs/ssr-dom-shim/",
39
+ "@lit-labs/ssr-dom-shim": "/node_modules/@lit-labs/ssr-dom-shim/index.js",
40
+ "@lit/reactive-element/": "/node_modules/@lit/reactive-element/",
41
+ "@lit/reactive-element": "/node_modules/@lit/reactive-element/reactive-element.js",
42
+ "@types/trusted-types/": "/node_modules/@types/trusted-types/",
43
+ "abstract-level/": "/node_modules/abstract-level/",
44
+ "abstract-level": "/node_modules/abstract-level/index.js",
45
+ "base64-js/": "/node_modules/base64-js/",
46
+ "base64-js": "/node_modules/base64-js/index.js",
47
+ "browser-level/": "/node_modules/browser-level/",
48
+ "browser-level": "/node_modules/browser-level/index.js",
49
+ "buffer/": "/node_modules/buffer/",
50
+ "buffer": "/node_modules/buffer/index.js",
51
+ "classic-level/": "/node_modules/classic-level/",
52
+ "classic-level": "/node_modules/classic-level/index.js",
53
+ "ieee754/": "/node_modules/ieee754/",
54
+ "ieee754": "/node_modules/ieee754/index.js",
55
+ "is-buffer/": "/node_modules/is-buffer/",
56
+ "is-buffer": "/node_modules/is-buffer/index.js",
57
+ "level/": "/node_modules/level/",
58
+ "level": "/node_modules/level/index.js",
59
+ "level-supports/": "/node_modules/level-supports/",
60
+ "level-transcoder/": "/node_modules/level-transcoder/",
61
+ "level-transcoder": "/node_modules/level-transcoder/index.js",
62
+ "lit/": "/node_modules/lit/",
63
+ "lit": "/node_modules/lit/index.js",
64
+ "lit-element/": "/node_modules/lit-element/",
65
+ "lit-element": "/node_modules/lit-element/index.js",
66
+ "lit-html/": "/node_modules/lit-html/",
67
+ "lit-html": "/node_modules/lit-html/lit-html.js",
68
+ "maybe-combine-errors/": "/node_modules/maybe-combine-errors/",
69
+ "module-error/": "/node_modules/module-error/",
70
+ "napi-macros/": "/node_modules/napi-macros/",
71
+ "napi-macros": "/node_modules/napi-macros/index.js",
72
+ "node-gyp-build/": "/node_modules/node-gyp-build/",
73
+ "node-gyp-build": "/node_modules/node-gyp-build/index.js"
74
+ },
75
+ "scopes": {}
76
+ }
77
+
78
+ </script>
79
+
80
+
81
+ <script>
82
+ // determine dev mode
83
+ const params = new URLSearchParams(location.search)
84
+ const isDevMode = params.has("dev")
85
+ ? params.get("dev") !== "false"
86
+ : (
87
+ location.hostname === "localhost" ||
88
+ location.hostname.startsWith("192.168.") ||
89
+ location.hostname.startsWith("10.0.") ||
90
+ location.hostname.endsWith("trycloudflare.com")
91
+ )
92
+
93
+ // create and insert a script element
94
+ function script(attributes) {
95
+ const element = document.createElement("script")
96
+ element.defer = true
97
+ for (const [key, value] of Object.entries(attributes))
98
+ element.setAttribute(key, value === true ?"" :value)
99
+ document.head.appendChild(element)
100
+ }
101
+
102
+ // launch dev module
103
+ if (isDevMode) {
104
+ document.title = "[dev] " + document.title
105
+ script({type: "module", src: "demo/main.bundle.js?v=f330da85"})
106
+ }
107
+
108
+ // launch prod module
109
+ else {
110
+ script({type: "module", src: "demo/main.bundle.min.js?v=5fedf132"})
111
+ }
112
+ </script>
113
+
114
+
115
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.0/cdn/themes/dark.css" />
116
+ <!-- loading every sholeace component for now (should be cherry picked instead) --!>
117
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.0/cdn/shoelace.js" ></script>
118
+
119
+ </head>
120
+ <body>
121
+
122
+ <header class=title>
123
+ <img alt="" src="/assets/favicon.png"/>
124
+ <div>
125
+ <h1>Quay</h1>
126
+ <span class=version>v0.0.0-1</span>
127
+ </div>
128
+ </header>
129
+
130
+ <div class=components>
131
+
132
+ <div class="component dropzone">
133
+ <h4>quay-dropzone</h2>
134
+ <quay-dropzone></quay-dropzone>
135
+ </div>
136
+
137
+ <div class="component outliner">
138
+ <h4>quay-outliner</h2>
139
+ <quay-outliner></quay-outliner>
140
+ </div>
141
+
142
+ <div class="component searchbar">
143
+ <h4>quay-searchbar</h2>
144
+ <quay-searchbar></quay-searchbar>
145
+ </div>
146
+
147
+ <div class="component breadcrumb">
148
+ <h4>quay-breadcrumb</h2>
149
+ <quay-breadcrumb></quay-breadcrumb>
150
+ </div>
151
+
152
+ <div class="component filter">
153
+ <h4>quay-filter</h2>
154
+ <quay-filter></quay-filter>
155
+ </div>
156
+
157
+ <div class="component sort">
158
+ <h4>quay-sort</h2>
159
+ <quay-sort></quay-sort>
160
+ </div>
161
+
162
+ <div class="component browser">
163
+ <h4>quay-browser</h2>
164
+ <quay-browser></quay-browser>
165
+ </div>
166
+
167
+ </div>
168
+
169
+ </body>
170
+ </html>
@@ -0,0 +1,3 @@
1
+ import "@benev/slate/x/node.js";
2
+ declare const _default: import("@benev/turtle").Template<unknown>;
3
+ export default _default;
@@ -0,0 +1,87 @@
1
+ import "@benev/slate/x/node.js";
2
+ import { template, html, easypage, headScripts, git_commit_hash, read_file, renderSocialCard, read_json } from "@benev/turtle";
3
+ const domain = "quay.e280.org";
4
+ const favicon = "/assets/favicon.png";
5
+ export default template(async (basic) => {
6
+ const path = basic.path(import.meta.url);
7
+ const hash = await git_commit_hash();
8
+ const version = (await read_json("package.json")).version;
9
+ return easypage({
10
+ path,
11
+ dark: true,
12
+ title: "Quay",
13
+ css: "demo/main.css",
14
+ head: html `
15
+ <link rel="icon" href="${favicon}"/>
16
+ <meta data-commit-hash="${hash}"/>
17
+
18
+ ${renderSocialCard({
19
+ themeColor: "#eb6f1d",
20
+ siteName: domain,
21
+ title: "Quay — File-browser UI Framework",
22
+ description: "Customizable outliner web ui toolkit for nested things",
23
+ image: `https://${domain}${favicon}`,
24
+ url: `https://${domain}/`,
25
+ })}
26
+
27
+ ${headScripts({
28
+ devModulePath: await path.version.root("demo/main.bundle.js"),
29
+ prodModulePath: await path.version.root("demo/main.bundle.min.js"),
30
+ importmapContent: await read_file("x/importmap.json"),
31
+ })}
32
+
33
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.0/cdn/themes/dark.css" />
34
+ <!-- loading every sholeace component for now (should be cherry picked instead) --!>
35
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.0/cdn/shoelace.js" ></script>
36
+ `,
37
+ body: html `
38
+ <header class=title>
39
+ <img alt="" src="/assets/favicon.png"/>
40
+ <div>
41
+ <h1>Quay</h1>
42
+ <span class=version>v${version}</span>
43
+ </div>
44
+ </header>
45
+
46
+ <div class=components>
47
+
48
+ <div class="component dropzone">
49
+ <h4>quay-dropzone</h2>
50
+ <quay-dropzone></quay-dropzone>
51
+ </div>
52
+
53
+ <div class="component outliner">
54
+ <h4>quay-outliner</h2>
55
+ <quay-outliner></quay-outliner>
56
+ </div>
57
+
58
+ <div class="component searchbar">
59
+ <h4>quay-searchbar</h2>
60
+ <quay-searchbar></quay-searchbar>
61
+ </div>
62
+
63
+ <div class="component breadcrumb">
64
+ <h4>quay-breadcrumb</h2>
65
+ <quay-breadcrumb></quay-breadcrumb>
66
+ </div>
67
+
68
+ <div class="component filter">
69
+ <h4>quay-filter</h2>
70
+ <quay-filter></quay-filter>
71
+ </div>
72
+
73
+ <div class="component sort">
74
+ <h4>quay-sort</h2>
75
+ <quay-sort></quay-sort>
76
+ </div>
77
+
78
+ <div class="component browser">
79
+ <h4>quay-browser</h2>
80
+ <quay-browser></quay-browser>
81
+ </div>
82
+
83
+ </div>
84
+ `,
85
+ });
86
+ });
87
+ //# sourceMappingURL=index.html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.html.js","sourceRoot":"","sources":["../s/index.html.ts"],"names":[],"mappings":"AAAA,OAAO,wBAAwB,CAAA;AAC/B,OAAO,EAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,EAAE,SAAS,EAAC,MAAM,eAAe,CAAA;AAE5H,MAAM,MAAM,GAAG,eAAe,CAAA;AAC9B,MAAM,OAAO,GAAG,qBAAqB,CAAA;AAErC,eAAe,QAAQ,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;IACrC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACxC,MAAM,IAAI,GAAG,MAAM,eAAe,EAAE,CAAA;IACpC,MAAM,OAAO,GAAG,CAAC,MAAM,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,OAAiB,CAAA;IAEnE,OAAO,QAAQ,CAAC;QACf,IAAI;QACJ,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,MAAM;QACb,GAAG,EAAE,eAAe;QACpB,IAAI,EAAE,IAAI,CAAA;4BACgB,OAAO;6BACN,IAAI;;KAE5B,gBAAgB,CAAC;YAClB,UAAU,EAAE,SAAS;YACrB,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,kCAAkC;YACzC,WAAW,EAAE,wDAAwD;YACrE,KAAK,EAAE,WAAW,MAAM,GAAG,OAAO,EAAE;YACpC,GAAG,EAAE,WAAW,MAAM,GAAG;SACzB,CAAC;;KAEA,WAAW,CAAC;YACb,aAAa,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC;YAC7D,cAAc,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC;YAClE,gBAAgB,EAAE,MAAM,SAAS,CAAC,kBAAkB,CAAC;SACrD,CAAC;;;;;GAKF;QACD,IAAI,EAAE,IAAI,CAAA;;;;;4BAKgB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0ChC;KACD,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"}
package/x/index.js ADDED
@@ -0,0 +1,9 @@
1
+ export { register, css } from "@benev/slate";
2
+ export * from "./cellar/index.js";
3
+ export * from "./dom/components.js";
4
+ import { Permissions } from "./logic/permissions.js";
5
+ const Quay = {
6
+ permissions: Permissions,
7
+ };
8
+ export default Quay;
9
+ //# sourceMappingURL=index.js.map
package/x/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../s/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAE,GAAG,EAAC,MAAM,cAAc,CAAA;AAE1C,cAAc,mBAAmB,CAAA;AAEjC,cAAc,qBAAqB,CAAA;AACnC,OAAO,EAAC,WAAW,EAAC,MAAM,wBAAwB,CAAA;AAElD,MAAM,IAAI,GAAG;IACZ,WAAW,EAAE,WAAW;CACxB,CAAA;AAED,eAAe,IAAI,CAAA"}
@@ -0,0 +1,17 @@
1
+ import { Clade } from "./parts/clade.js";
2
+ import { Hierarchy } from "./parts/hierarchy.js";
3
+ import { CodexItem } from "./parts/codex-item.js";
4
+ import { Id, Schema, Taxons } from "./parts/types.js";
5
+ export declare class Codex<Sc extends Schema> {
6
+ #private;
7
+ clade: Clade<Sc>;
8
+ hierarchy: Hierarchy;
9
+ static setup<Sc extends Schema>(taxons: Taxons<Sc>): Codex<Sc>;
10
+ constructor(clade: Clade<Sc>, hierarchy: Hierarchy);
11
+ /** create an item, not yet added to hierarchy */
12
+ create<K extends keyof Sc["specimens"]>(kind: K, specimen: Sc["specimens"][K]): CodexItem<Sc, keyof Sc["specimens"]>;
13
+ /** add an item to the hierachy as a root root */
14
+ root<I extends CodexItem<Sc>>(item: I): I;
15
+ /** get an item by its id */
16
+ require(id: Id): CodexItem<Sc>;
17
+ }
@@ -0,0 +1,39 @@
1
+ import { MapG } from "@e280/stz";
2
+ import { Clade } from "./parts/clade.js";
3
+ import { Taxonomy } from "./parts/taxonomy.js";
4
+ import { Hierarchy } from "./parts/hierarchy.js";
5
+ import { CodexItem } from "./parts/codex-item.js";
6
+ import { generateId } from "./utils/generate-id.js";
7
+ export class Codex {
8
+ clade;
9
+ hierarchy;
10
+ static setup(taxons) {
11
+ const taxonomy = new Taxonomy(taxons);
12
+ const clade = new Clade(taxonomy);
13
+ const hierarchy = new Hierarchy();
14
+ return new this(clade, hierarchy);
15
+ }
16
+ #items = new MapG();
17
+ constructor(clade, hierarchy) {
18
+ this.clade = clade;
19
+ this.hierarchy = hierarchy;
20
+ }
21
+ /** create an item, not yet added to hierarchy */
22
+ create(kind, specimen) {
23
+ const id = generateId();
24
+ this.clade.setSpecimen(id, kind, specimen);
25
+ const item = new CodexItem(this, id);
26
+ this.#items.set(id, item);
27
+ return item.signal.value;
28
+ }
29
+ /** add an item to the hierachy as a root root */
30
+ root(item) {
31
+ this.hierarchy.establishRoot(item.id);
32
+ return item.signal.value;
33
+ }
34
+ /** get an item by its id */
35
+ require(id) {
36
+ return this.#items.require(id).signal.value;
37
+ }
38
+ }
39
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../../s/logic/aspects/codex/codex.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAE9B,OAAO,EAAC,KAAK,EAAC,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAC,SAAS,EAAC,MAAM,sBAAsB,CAAA;AAC9C,OAAO,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAA;AAC/C,OAAO,EAAC,UAAU,EAAC,MAAM,wBAAwB,CAAA;AAGjD,MAAM,OAAO,KAAK;IAWT;IACA;IAXR,MAAM,CAAC,KAAK,CAAoB,MAAkB;QACjD,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAK,MAAM,CAAC,CAAA;QACzC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAA;QACjC,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAA;QACjC,OAAO,IAAI,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IAClC,CAAC;IAED,MAAM,GAAG,IAAI,IAAI,EAAqB,CAAA;IAEtC,YACQ,KAAgB,EAChB,SAAoB;QADpB,UAAK,GAAL,KAAK,CAAW;QAChB,cAAS,GAAT,SAAS,CAAW;IACzB,CAAC;IAEJ,iDAAiD;IACjD,MAAM,CAAkC,IAAO,EAAE,QAA4B;QAC5E,MAAM,EAAE,GAAG,UAAU,EAAE,CAAA;QACvB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;QAC1C,MAAM,IAAI,GAAG,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QACpC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAA;IACzB,CAAC;IAED,iDAAiD;IACjD,IAAI,CAA0B,IAAO;QACpC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACrC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAA;IACzB,CAAC;IAED,4BAA4B;IAC5B,OAAO,CAAC,EAAM;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;IAC5C,CAAC;CACD"}
@@ -0,0 +1,13 @@
1
+ import "@benev/slate/x/node.js";
2
+ import { AsSchema, Taxon } from "./parts/types.js";
3
+ export type FilesystemSchema = AsSchema<{
4
+ taxon: Taxon;
5
+ specimens: {
6
+ folder: {
7
+ label: string;
8
+ };
9
+ file: {
10
+ label: string;
11
+ };
12
+ };
13
+ }>;
@@ -0,0 +1,42 @@
1
+ import "@benev/slate/x/node.js";
2
+ import { repeat_string } from "@benev/turtle";
3
+ import { Codex } from "./codex.js";
4
+ // we create a codex that uses our schema, and specifies these icons
5
+ const codex = Codex.setup({
6
+ folder: { icon: "📁" },
7
+ file: { icon: "📄" },
8
+ });
9
+ // let's create a folder with some crap
10
+ const folder = codex.create("folder", { label: "project" });
11
+ const readme = codex.create("file", { label: "README.md" });
12
+ const changelog = codex.create("file", { label: "CHANGELOG.md" });
13
+ // let's create a subfolder with more crap
14
+ const src = codex.create("folder", { label: "src" });
15
+ const index = codex.create("file", { label: "index.ts" });
16
+ const types = codex.create("file", { label: "types.ts" });
17
+ // we attach the folder as the root, and attach its children
18
+ codex.root(folder)
19
+ .attach(readme)
20
+ .attach(changelog)
21
+ .attach(src); // <-- this is the subfolder
22
+ // and we attach the subfolder items to it
23
+ src
24
+ .attach(index)
25
+ .attach(types);
26
+ // we can crawl any folder!
27
+ // 👇
28
+ for (const [item, ancestors] of folder.crawl()) {
29
+ const indent = repeat_string(ancestors.length, " ");
30
+ const specimen = item.specimen;
31
+ const label = item.kind === "folder"
32
+ ? specimen.label + "/"
33
+ : specimen.label;
34
+ console.log(indent + label);
35
+ }
36
+ // project/
37
+ // README.md
38
+ // CHANGELOG.md
39
+ // src/
40
+ // index.ts
41
+ // types.ts
42
+ //# sourceMappingURL=example.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"example.js","sourceRoot":"","sources":["../../../../s/logic/aspects/codex/example.ts"],"names":[],"mappings":"AACA,OAAO,wBAAwB,CAAA;AAC/B,OAAO,EAAC,aAAa,EAAC,MAAM,eAAe,CAAA;AAE3C,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAA;AAgBhC,oEAAoE;AACpE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAmB;IAC3C,MAAM,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC;IACpB,IAAI,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC;CAClB,CAAC,CAAA;AAEF,uCAAuC;AACvC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAC,KAAK,EAAE,SAAS,EAAC,CAAC,CAAA;AACzD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,EAAC,KAAK,EAAE,WAAW,EAAC,CAAC,CAAA;AACzD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,EAAC,KAAK,EAAE,cAAc,EAAC,CAAC,CAAA;AAE/D,0CAA0C;AAC1C,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAC,KAAK,EAAE,KAAK,EAAC,CAAC,CAAA;AAClD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,EAAC,KAAK,EAAE,UAAU,EAAC,CAAC,CAAA;AACvD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,EAAC,KAAK,EAAE,UAAU,EAAC,CAAC,CAAA;AAEvD,4DAA4D;AAC5D,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;KAChB,MAAM,CAAC,MAAM,CAAC;KACd,MAAM,CAAC,SAAS,CAAC;KACjB,MAAM,CAAC,GAAG,CAAC,CAAA,CAAC,4BAA4B;AAE1C,0CAA0C;AAC1C,GAAG;KACD,MAAM,CAAC,KAAK,CAAC;KACb,MAAM,CAAC,KAAK,CAAC,CAAA;AAEd,6CAA6C;AAC7C,wCAAwC;AACzC,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;IAChD,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,KAAK,QAAQ;QACnC,CAAC,CAAC,QAAQ,CAAC,KAAK,GAAG,GAAG;QACtB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAA;IACjB,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,CAAA;AAC5B,CAAC;AAED,WAAW;AACX,cAAc;AACd,iBAAiB;AACjB,SAAS;AACT,eAAe;AACf,eAAe"}
@@ -0,0 +1,16 @@
1
+ import { Taxonomy } from "./taxonomy.js";
2
+ import { Id, Kind, Schema } from "./types.js";
3
+ /** Tracks what kind and specimen data is associated with each item id. */
4
+ export declare class Clade<Sc extends Schema> {
5
+ #private;
6
+ taxonomy: Taxonomy<Sc>;
7
+ onChange: import("@e280/stz").Sub<[]>;
8
+ constructor(taxonomy: Taxonomy<Sc>);
9
+ getSpecimen<K extends Kind<Sc> = Kind<Sc>>(id: string): [K, Sc["specimens"][K]];
10
+ setSpecimen<K extends Kind<Sc>>(id: string, kind: K, specimen: Sc["specimens"][K]): void;
11
+ query<K extends Kind<Sc> = Kind<Sc>>(id: Id): {
12
+ kind: K;
13
+ taxon: Sc["taxon"];
14
+ specimen: Sc["specimens"][K];
15
+ };
16
+ }
@@ -0,0 +1,23 @@
1
+ import { MapG, sub } from "@e280/stz";
2
+ /** Tracks what kind and specimen data is associated with each item id. */
3
+ export class Clade {
4
+ taxonomy;
5
+ onChange = sub();
6
+ #specimens = new MapG();
7
+ constructor(taxonomy) {
8
+ this.taxonomy = taxonomy;
9
+ }
10
+ getSpecimen(id) {
11
+ return this.#specimens.require(id);
12
+ }
13
+ setSpecimen(id, kind, specimen) {
14
+ this.#specimens.set(id, [kind, specimen]);
15
+ this.onChange.pub();
16
+ }
17
+ query(id) {
18
+ const [kind, specimen] = this.getSpecimen(id);
19
+ const taxon = this.taxonomy.taxon(kind);
20
+ return { kind, taxon, specimen };
21
+ }
22
+ }
23
+ //# sourceMappingURL=clade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clade.js","sourceRoot":"","sources":["../../../../../s/logic/aspects/codex/parts/clade.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAE,GAAG,EAAC,MAAM,WAAW,CAAA;AAInC,0EAA0E;AAC1E,MAAM,OAAO,KAAK;IAIE;IAHnB,QAAQ,GAAG,GAAG,EAAE,CAAA;IAChB,UAAU,GAAG,IAAI,IAAI,EAAmC,CAAA;IAExD,YAAmB,QAAsB;QAAtB,aAAQ,GAAR,QAAQ,CAAc;IAAG,CAAC;IAE7C,WAAW,CAAgC,EAAU;QACpD,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAA4B,CAAA;IAC9D,CAAC;IAED,WAAW,CAAqB,EAAU,EAAE,IAAO,EAAE,QAA4B;QAChF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;QACzC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAA;IACpB,CAAC;IAED,KAAK,CAAgC,EAAM;QAC1C,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC,WAAW,CAAI,EAAE,CAAC,CAAA;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACvC,OAAO,EAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAC,CAAA;IAC/B,CAAC;CACD"}
@@ -0,0 +1,33 @@
1
+ import { Codex } from "../codex.js";
2
+ import { Id, Kind, Schema } from "./types.js";
3
+ /**
4
+ * Codex Item
5
+ * - Quay's concept of a nestable thing.
6
+ * - ergonomic handle which consolidates taxonomy, clade, and hierarchy functionality.
7
+ */
8
+ export declare class CodexItem<Sc extends Schema = any, K extends Kind<Sc> = Kind<Sc>> {
9
+ private codex;
10
+ id: Id;
11
+ signal: import("@benev/slate").Signal<this>;
12
+ constructor(codex: Codex<Sc>, id: Id);
13
+ get kind(): K;
14
+ isKind<K2 extends Kind<Sc>>(kind: K2): this is CodexItem<Sc, K2>;
15
+ /** get information about the type of entity */
16
+ get taxon(): Sc["taxon"];
17
+ /** get information about this specific entity */
18
+ get specimen(): Sc["specimens"][K];
19
+ /** get this item's parent item, or undefined if it's not attached */
20
+ get parent(): CodexItem<Sc> | undefined;
21
+ /** get an array of this item's children */
22
+ get children(): CodexItem<Sc>[];
23
+ /** add items as children */
24
+ attach(...items: CodexItem<Sc>[]): this;
25
+ /** detach this item from the hierarchy completely */
26
+ detach(): void;
27
+ /** create a new item that will be a child */
28
+ create<K extends keyof Sc["specimens"]>(kind: K, specimen: Sc["specimens"][K]): CodexItem<Sc, keyof Sc["specimens"]>;
29
+ /** create a new item that will be a child */
30
+ destroy(): void;
31
+ /** iterate over this item and all its descendants */
32
+ crawl(predicate?: (item: CodexItem<Sc>, path: CodexItem<Sc>[]) => boolean): Generator<[CodexItem<Sc, keyof Sc["specimens"]>, CodexItem<Sc, keyof Sc["specimens"]>[]], void, unknown>;
33
+ }
@@ -0,0 +1,74 @@
1
+ import { signal } from "@benev/slate";
2
+ /**
3
+ * Codex Item
4
+ * - Quay's concept of a nestable thing.
5
+ * - ergonomic handle which consolidates taxonomy, clade, and hierarchy functionality.
6
+ */
7
+ export class CodexItem {
8
+ codex;
9
+ id;
10
+ signal = signal(this);
11
+ constructor(codex, id) {
12
+ this.codex = codex;
13
+ this.id = id;
14
+ }
15
+ get kind() {
16
+ return this.codex.clade.query(this.id).kind;
17
+ }
18
+ isKind(kind) {
19
+ return (kind === this.kind);
20
+ }
21
+ /** get information about the type of entity */
22
+ get taxon() {
23
+ return this.codex.clade.query(this.id).taxon;
24
+ }
25
+ /** get information about this specific entity */
26
+ get specimen() {
27
+ return this.codex.clade.query(this.id).specimen;
28
+ }
29
+ /** get this item's parent item, or undefined if it's not attached */
30
+ get parent() {
31
+ const parent = this.codex.hierarchy.getParent(this.id);
32
+ return parent
33
+ ? this.codex.require(parent)
34
+ : undefined;
35
+ }
36
+ /** get an array of this item's children */
37
+ get children() {
38
+ // TODO actually replace this with a children() iterator, could be a perf win for supermassive sets
39
+ return [...this.codex.hierarchy.getChildren(this.id)]
40
+ .map(id => this.codex.require(id));
41
+ }
42
+ /** add items as children */
43
+ attach(...items) {
44
+ this.codex.hierarchy.attach(this.id, ...items.map(i => i.id));
45
+ this.signal.publish();
46
+ return this;
47
+ }
48
+ /** detach this item from the hierarchy completely */
49
+ detach() {
50
+ this.codex.hierarchy.detach(this.id);
51
+ this.signal.publish();
52
+ }
53
+ /** create a new item that will be a child */
54
+ create(kind, specimen) {
55
+ const item = this.codex.create(kind, specimen);
56
+ this.attach(item);
57
+ return item;
58
+ }
59
+ /** create a new item that will be a child */
60
+ destroy() {
61
+ this.codex.hierarchy.destroy(this.id);
62
+ this.signal.publish();
63
+ }
64
+ /** iterate over this item and all its descendants */
65
+ *crawl(predicate = () => true) {
66
+ const iterator = this.codex.hierarchy.crawl(this.id, (id, path) => predicate(this.codex.require(id), path.map(id => this.codex.require(id))));
67
+ for (const [id, path] of iterator)
68
+ yield [
69
+ this.codex.require(id),
70
+ path.map(id => this.codex.require(id)),
71
+ ];
72
+ }
73
+ }
74
+ //# sourceMappingURL=codex-item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-item.js","sourceRoot":"","sources":["../../../../../s/logic/aspects/codex/parts/codex-item.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { Id } from "./types.js";
2
+ /**
3
+ * Tree of nestable things.
4
+ * - Things can have multiple children.
5
+ * - Things can only have one parent.
6
+ * - Things can be orphans (bring your own concept of a "root").
7
+ */
8
+ export declare class Hierarchy {
9
+ #private;
10
+ has(id: Id): boolean;
11
+ getChildren(id: Id): Set<string>;
12
+ getParent(id: Id): string | undefined;
13
+ /** establish an id as a root with no parents, but ready to accept children */
14
+ establishRoot(root: Id): void;
15
+ /** give a parent some children */
16
+ attach(parent: Id, ...children: Id[]): void;
17
+ /** detach this id from its parent in the hierarchy */
18
+ detach(id: Id): undefined;
19
+ /** destroy all relations associated with this id, and all its descendants */
20
+ destroy(id: Id): void;
21
+ /** iterate over this id and all its descendants */
22
+ crawl(id: Id, predicate?: (id: Id, path: Id[]) => boolean): Generator<[string, string[]], void, unknown>;
23
+ }
@@ -0,0 +1,69 @@
1
+ import { MapG } from "@e280/stz";
2
+ /**
3
+ * Tree of nestable things.
4
+ * - Things can have multiple children.
5
+ * - Things can only have one parent.
6
+ * - Things can be orphans (bring your own concept of a "root").
7
+ */
8
+ export class Hierarchy {
9
+ #children = new MapG();
10
+ #parents = new MapG();
11
+ has(id) {
12
+ return this.#children.has(id);
13
+ }
14
+ getChildren(id) {
15
+ return this.#children.require(id);
16
+ }
17
+ getParent(id) {
18
+ return this.#parents.get(id);
19
+ }
20
+ /** establish an id as a root with no parents, but ready to accept children */
21
+ establishRoot(root) {
22
+ this.#children.set(root, new Set());
23
+ }
24
+ /** give a parent some children */
25
+ attach(parent, ...children) {
26
+ const siblings = this.getChildren(parent);
27
+ for (const childId of children) {
28
+ if (this.getParent(childId))
29
+ throw new Error(`child already has parent`);
30
+ siblings.add(childId);
31
+ this.#parents.set(childId, parent);
32
+ this.#children.set(childId, new Set());
33
+ }
34
+ }
35
+ /** detach this id from its parent in the hierarchy */
36
+ detach(id) {
37
+ if (!this.has(id))
38
+ return undefined;
39
+ const parent = this.getParent(id);
40
+ if (parent) {
41
+ const siblings = this.getChildren(parent);
42
+ siblings.delete(id);
43
+ this.#parents.delete(id);
44
+ }
45
+ }
46
+ /** destroy all relations associated with this id, and all its descendants */
47
+ destroy(id) {
48
+ const tree = [...this.crawl(id)];
49
+ for (const [id] of tree) {
50
+ this.#children.delete(id);
51
+ this.#parents.delete(id);
52
+ }
53
+ }
54
+ /** iterate over this id and all its descendants */
55
+ *crawl(id, predicate = () => true) {
56
+ const todo = [[id, []]];
57
+ const seen = new Set();
58
+ while (todo.length) {
59
+ const [id, path] = todo.shift();
60
+ if (seen.has(id) || !predicate(id, path))
61
+ continue;
62
+ seen.add(id);
63
+ yield [id, path];
64
+ for (const childId of this.getChildren(id))
65
+ todo.push([childId, [...path, id]]);
66
+ }
67
+ }
68
+ }
69
+ //# sourceMappingURL=hierarchy.js.map