sol-components 2.1.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.
Files changed (150) hide show
  1. package/README.md +7 -0
  2. package/core/activate.js +27 -0
  3. package/core/adopt.js +71 -0
  4. package/core/auth-core.js +73 -0
  5. package/core/auth-fetch.js +154 -0
  6. package/core/component-mount.js +110 -0
  7. package/core/defaults.js +48 -0
  8. package/core/define.js +15 -0
  9. package/core/display-target.js +166 -0
  10. package/core/edit-placements.js +28 -0
  11. package/core/editor-self.js +127 -0
  12. package/core/editor.js +162 -0
  13. package/core/events.js +27 -0
  14. package/core/extension-points.js +189 -0
  15. package/core/form-utils.js +210 -0
  16. package/core/from-query.js +138 -0
  17. package/core/from-rdf.js +52 -0
  18. package/core/here.js +33 -0
  19. package/core/include-core.js +73 -0
  20. package/core/inrupt-global.js +18 -0
  21. package/core/menu-consumer.js +41 -0
  22. package/core/menu-rdf.js +154 -0
  23. package/core/pod-ops.js +392 -0
  24. package/core/pod-registry.js +82 -0
  25. package/core/popup-proxy.js +255 -0
  26. package/core/rdf-core.js +280 -0
  27. package/core/rdf-render.js +136 -0
  28. package/core/rdf-utils.js +411 -0
  29. package/core/rdf.js +154 -0
  30. package/core/services.js +106 -0
  31. package/core/shape-to-form.js +741 -0
  32. package/core/sparql-safety.js +20 -0
  33. package/core/utils.js +196 -0
  34. package/dist/importmap-cdn.json +49 -0
  35. package/dist/importmap-local.json +49 -0
  36. package/dist/sol-loader.manifest.json +140 -0
  37. package/dist/vendor/@comunica-query-sparql.js +137851 -0
  38. package/dist/vendor/@inrupt-solid-client-authn-browser.js +7503 -0
  39. package/dist/vendor/dompurify.js +1476 -0
  40. package/dist/vendor/ical.js.js +9739 -0
  41. package/dist/vendor/marked.js +85 -0
  42. package/dist/vendor/n3.js +14670 -0
  43. package/dist/vendor/rdf-validate-shacl.js +6970 -0
  44. package/dist/vendor/rdflib.js +35172 -0
  45. package/dist/vendor/solid-logic.js +6819 -0
  46. package/dist/vendor/solid-ui.js +21945 -0
  47. package/node/sol-form.js +133 -0
  48. package/node/sol-include.js +55 -0
  49. package/node/sol-login.js +632 -0
  50. package/node/sol-menu.js +639 -0
  51. package/node/sol-query.js +116 -0
  52. package/package.json +133 -0
  53. package/web/menu-from-rdf.js +23 -0
  54. package/web/scripts/prefs.js +25 -0
  55. package/web/sol-accordion.js +114 -0
  56. package/web/sol-basic.js +50 -0
  57. package/web/sol-breadcrumb.js +131 -0
  58. package/web/sol-button.js +244 -0
  59. package/web/sol-calendar.js +465 -0
  60. package/web/sol-default.js +118 -0
  61. package/web/sol-dropdown-button.js +222 -0
  62. package/web/sol-feed.js +1336 -0
  63. package/web/sol-form.js +949 -0
  64. package/web/sol-full.js +43 -0
  65. package/web/sol-gallery.js +303 -0
  66. package/web/sol-include.js +246 -0
  67. package/web/sol-live-edit.js +415 -0
  68. package/web/sol-login.js +856 -0
  69. package/web/sol-menu.js +593 -0
  70. package/web/sol-modal.js +377 -0
  71. package/web/sol-pod-extras.js +17 -0
  72. package/web/sol-pod-ops.js +680 -0
  73. package/web/sol-pod.js +1039 -0
  74. package/web/sol-query.js +546 -0
  75. package/web/sol-rolodex.js +95 -0
  76. package/web/sol-search.js +402 -0
  77. package/web/sol-settings.js +199 -0
  78. package/web/sol-solidos.js +93 -0
  79. package/web/sol-tabs.js +445 -0
  80. package/web/sol-time.js +194 -0
  81. package/web/sol-tree-edit.js +492 -0
  82. package/web/sol-wac.js +456 -0
  83. package/web/sol-weather.js +337 -0
  84. package/web/sol-window.js +142 -0
  85. package/web/styles/buttons-css.js +108 -0
  86. package/web/styles/help.css +242 -0
  87. package/web/styles/root.css +112 -0
  88. package/web/styles/sol-accordion-css.js +97 -0
  89. package/web/styles/sol-calendar-css.js +154 -0
  90. package/web/styles/sol-feed-css.js +475 -0
  91. package/web/styles/sol-form-css.js +471 -0
  92. package/web/styles/sol-gallery-css.js +181 -0
  93. package/web/styles/sol-include-css.js +95 -0
  94. package/web/styles/sol-live-edit-css.js +84 -0
  95. package/web/styles/sol-live-edit.css +101 -0
  96. package/web/styles/sol-login-css.js +116 -0
  97. package/web/styles/sol-menu-css.js +145 -0
  98. package/web/styles/sol-modal-css.js +134 -0
  99. package/web/styles/sol-pod-css.js +187 -0
  100. package/web/styles/sol-pod-modal-css.js +203 -0
  101. package/web/styles/sol-query-css.js +140 -0
  102. package/web/styles/sol-query-help.css +267 -0
  103. package/web/styles/sol-query-one-pager.css +67 -0
  104. package/web/styles/sol-search-css.js +157 -0
  105. package/web/styles/sol-solidos-css.js +7 -0
  106. package/web/styles/sol-tabs-css.js +114 -0
  107. package/web/styles/sol-time-css.js +30 -0
  108. package/web/styles/sol-wac-css.js +73 -0
  109. package/web/styles/sol-weather-css.js +59 -0
  110. package/web/styles/solid-logo.svg +9 -0
  111. package/web/styles/view-accordion-css.js +66 -0
  112. package/web/styles/view-anchorlist-css.js +22 -0
  113. package/web/styles/view-autocomplete-css.js +59 -0
  114. package/web/styles/view-rolodex-css.js +102 -0
  115. package/web/styles/view-select-css.js +21 -0
  116. package/web/utils/calendar-fetch.js +388 -0
  117. package/web/utils/code-mirror-editor.js +82 -0
  118. package/web/utils/commons-fetch.js +108 -0
  119. package/web/utils/feed-edit.js +159 -0
  120. package/web/utils/feed-edit.smoke.mjs +74 -0
  121. package/web/utils/feed-fetch.js +573 -0
  122. package/web/utils/live-edit-help/csv.js +64 -0
  123. package/web/utils/live-edit-help/graphviz.js +41 -0
  124. package/web/utils/live-edit-help/jsonld.js +55 -0
  125. package/web/utils/live-edit-help/markdown.js +52 -0
  126. package/web/utils/live-edit-help/mermaid.js +48 -0
  127. package/web/utils/live-edit-help/turtle.js +85 -0
  128. package/web/utils/rdf-config.js +125 -0
  129. package/web/utils/renderers/csv.js +124 -0
  130. package/web/utils/renderers/d3-force.js +82 -0
  131. package/web/utils/renderers/graphviz.js +13 -0
  132. package/web/utils/renderers/html.js +10 -0
  133. package/web/utils/renderers/jsonld.js +63 -0
  134. package/web/utils/renderers/markdown.js +19 -0
  135. package/web/utils/renderers/mermaid.js +54 -0
  136. package/web/utils/renderers/turtle.js +51 -0
  137. package/web/utils/sol-query-triple-patterns.js +151 -0
  138. package/web/utils/sol-query-ui.js +250 -0
  139. package/web/utils/sol-query-views.js +32 -0
  140. package/web/views/_helpers.js +34 -0
  141. package/web/views/accordion.js +133 -0
  142. package/web/views/anchorlist.js +59 -0
  143. package/web/views/auto-complete.js +183 -0
  144. package/web/views/dl.js +38 -0
  145. package/web/views/list.js +19 -0
  146. package/web/views/menu.js +56 -0
  147. package/web/views/rolodex.js +126 -0
  148. package/web/views/select.js +79 -0
  149. package/web/views/table.js +73 -0
  150. package/web/views/tabs.js +57 -0
@@ -0,0 +1,377 @@
1
+ /**
2
+ * <sol-modal> — Generic modal dialog web component.
3
+ * Attributes: title, size ("small" for compact prompts),
4
+ * source, content, component, handler (declarative trigger mode)
5
+ * Properties: handler (Function), headerActions (Element[]), onClose (Function)
6
+ * Methods: open(), close(), prompt(message, placeholder)
7
+ * Events: sol-ready, sol-close
8
+ *
9
+ * Imperative usage:
10
+ * const m = document.createElement('sol-modal');
11
+ * m.modalTitle = 'My File';
12
+ * m.handler = (body, footer, actions) => {
13
+ * // Populate the modal body directly, OR insert a <sol-tabs> when the
14
+ * // caller wants tabbed content.
15
+ * body.textContent = 'Hello';
16
+ * };
17
+ * m.open();
18
+ *
19
+ * // Prompt dialog:
20
+ * const val = await SolModal.prompt('Enter name:', 'default');
21
+ *
22
+ * Declarative trigger usage — any of source/content/component/handler turns
23
+ * the element into an inline button; clicking it opens the modal:
24
+ *
25
+ * <sol-modal source="foo.html">edit foo</sol-modal>
26
+ * <sol-modal content="<p>hi</p>">show hi</sol-modal>
27
+ * <sol-modal source="foo.ttl" component="sol-live-edit" format="turtle">
28
+ * edit foo
29
+ * </sol-modal>
30
+ * <sol-modal source="foo.ttl" handler="myHandler">edit foo</sol-modal>
31
+ *
32
+ * When `component` is set, sol-modal creates that element inside the modal
33
+ * body and forwards all attributes (except title/size/component/content/handler)
34
+ * to it.
35
+ *
36
+ * When `handler` is set as an attribute, its value names a global function
37
+ * (e.g. `window[name]`); the modal invokes it as `fn(body, footer, actions,
38
+ * { source, host })`. When `handler` is assigned as a property, the value
39
+ * itself is the function.
40
+ *
41
+ * The trigger button is exposed as `::part(trigger)` for external styling.
42
+ *
43
+ * Events (bubbling, composed):
44
+ * sol-ready — fires after the body is populated.
45
+ * detail: { body, mode: 'source'|'content'|'component'|'handler', element }
46
+ * sol-close — fires when the modal closes.
47
+ */
48
+
49
+ import { CSS, sheet as MODAL_SHEET } from './styles/sol-modal-css.js';
50
+ import { adopt } from '../core/adopt.js';
51
+ import { define } from '../core/define.js';
52
+ import './sol-include.js'; // source mode renders content through <sol-include>
53
+
54
+ const OWN_ATTRS = new Set(['title', 'size', 'component', 'content', 'source', 'handler']);
55
+
56
+ /**
57
+ * Generic modal dialog web component.
58
+ *
59
+ * Imperative usage: create the element, set `modalTitle` and `handler`,
60
+ * then call `open()`. The handler receives `(body, footer, actions)` to
61
+ * populate the modal content.
62
+ *
63
+ * Declarative trigger usage: any of `source`/`content`/`component`/`handler`
64
+ * attributes turns the element into an inline button; clicking opens the modal.
65
+ *
66
+ * @class SolModal
67
+ * @extends HTMLElement
68
+ * @attr {string} title - modal header title
69
+ * @attr {string} size - "small" for compact prompt-style dialogs
70
+ * @attr {string} source - URL to fetch and display (declarative trigger mode)
71
+ * @attr {string} content - inline HTML string to display (declarative trigger mode)
72
+ * @attr {string} component - sol-* tag name to create inside the modal body
73
+ * @attr {string} handler - global function name or Function for custom rendering
74
+ * @property {Function} handler - render callback: fn(body, footer, actions, { source, host })
75
+ * @property {Element[]} headerActions - extra buttons for the modal header
76
+ * @property {Function} onClose - callback invoked when the modal closes
77
+ * @fires sol-ready - detail: { body, mode, element }; body populated
78
+ * @fires sol-close - modal dismissed
79
+ */
80
+ class SolModal extends HTMLElement {
81
+ static get observedAttributes() { return ['title', 'size']; }
82
+
83
+ constructor() {
84
+ super();
85
+ this.attachShadow({ mode: 'open' });
86
+ this._cleanup = null;
87
+ this._onClose = null;
88
+ this._triggerMode = false;
89
+ this._handler = null;
90
+ this._extraStyles = [];
91
+ }
92
+
93
+ // Additional stylesheets (CSSStyleSheet instances or raw CSS strings) to
94
+ // adopt into the modal's shadow root on open(). Callers use this when
95
+ // their modal content renders classes defined outside the modal — e.g.
96
+ // <sol-pod> pushing its ACL/editor rules so they reach the modal scope.
97
+ get styles() { return this._extraStyles; }
98
+ set styles(arr) { this._extraStyles = Array.isArray(arr) ? arr : []; }
99
+
100
+ _isTriggerUsage() {
101
+ return this.hasAttribute('source')
102
+ || this.hasAttribute('content')
103
+ || this.hasAttribute('component')
104
+ || this.hasAttribute('handler');
105
+ }
106
+
107
+ get modalTitle() { return this.getAttribute('title') || ''; }
108
+ set modalTitle(v) { this.setAttribute('title', v); }
109
+
110
+ get handler() { return this._handler; }
111
+ set handler(fn) { this._handler = fn; }
112
+
113
+ get onClose() { return this._onClose; }
114
+ set onClose(fn) { this._onClose = fn; }
115
+
116
+ get body() { return this.shadowRoot.querySelector('.modal-body'); }
117
+ get footer() { return this.shadowRoot.querySelector('.modal-footer'); }
118
+ get headerActions() { return this.shadowRoot.querySelector('.modal-header-actions'); }
119
+
120
+ connectedCallback() {
121
+ if (this._isTriggerUsage() && !this.shadowRoot.firstChild) {
122
+ this._triggerMode = true;
123
+ this._renderTrigger();
124
+ }
125
+ }
126
+
127
+ _renderTrigger() {
128
+ const s = this.shadowRoot;
129
+ s.innerHTML = `<button class="sol-btn modal-trigger" part="trigger" type="button"><slot>Open</slot></button>`;
130
+ s.adoptedStyleSheets = [];
131
+ adopt(s, { sheet: MODAL_SHEET, css: CSS });
132
+ const btn = s.querySelector('.modal-trigger');
133
+ const a11y = this.getAttribute('aria-label') || this.getAttribute('title');
134
+ if (a11y) btn.setAttribute('aria-label', a11y);
135
+ const tip = this.getAttribute('title');
136
+ if (tip) btn.setAttribute('title', tip);
137
+ btn.addEventListener('click', () => this._openDeclarative());
138
+ }
139
+
140
+ _emitReady(body, mode, element = null) {
141
+ this.dispatchEvent(new CustomEvent('sol-ready', {
142
+ bubbles: true, composed: true,
143
+ detail: { body, mode, element }
144
+ }));
145
+ }
146
+
147
+ _resolveAttrHandler() {
148
+ const name = this.getAttribute('handler');
149
+ if (!name) return null;
150
+ const fn = (typeof window !== 'undefined' && window[name]) || null;
151
+ return typeof fn === 'function' ? fn : null;
152
+ }
153
+
154
+ _openDeclarative() {
155
+ const source = this.getAttribute('source');
156
+ const content = this.getAttribute('content');
157
+ const componentName = this.getAttribute('component');
158
+ const host = this;
159
+ const attrHandler = this._resolveAttrHandler();
160
+
161
+ this._handler = (body, footer, actions) => {
162
+ if (attrHandler) {
163
+ attrHandler(body, footer, actions, { source, host });
164
+ host._emitReady(body, 'handler', null);
165
+ return;
166
+ }
167
+ if (componentName) {
168
+ const el = document.createElement(componentName);
169
+ for (const a of host.attributes) {
170
+ if (!OWN_ATTRS.has(a.name)) el.setAttribute(a.name, a.value);
171
+ }
172
+ el.className = 'modal-body-component';
173
+ body.appendChild(el);
174
+ host._emitReady(body, 'component', el);
175
+ } else if (source != null) {
176
+ // Render through <sol-include> rather than a bare fetch, so the
177
+ // modal gets HTML/Markdown handling, the `selector` filter,
178
+ // DOMPurify sanitization (unless `trusted`), and Solid auth-fetch.
179
+ const inc = document.createElement('sol-include');
180
+ inc.setAttribute('source', source);
181
+ if (host.hasAttribute('selector')) inc.setAttribute('selector', host.getAttribute('selector'));
182
+ if (host.hasAttribute('trusted')) inc.setAttribute('trusted', '');
183
+ inc.className = 'modal-body-component';
184
+ body.appendChild(inc);
185
+ host._emitReady(body, 'source', inc);
186
+ } else if (content != null) {
187
+ body.innerHTML = content;
188
+ host._emitReady(body, 'content', null);
189
+ }
190
+ };
191
+ this.open();
192
+ }
193
+
194
+ attributeChangedCallback(name, oldV, newV) {
195
+ if (oldV === newV) return;
196
+ if (name === 'title') {
197
+ const el = this.shadowRoot.querySelector('.modal-title');
198
+ if (el) el.textContent = newV || '';
199
+ }
200
+ }
201
+
202
+ open() {
203
+ this._render();
204
+ if (!this.parentNode) document.body.appendChild(this);
205
+ this._invokeHandler();
206
+ }
207
+
208
+ _invokeHandler() {
209
+ if (typeof this._handler !== 'function') return;
210
+ if (typeof this._cleanup === 'function') { this._cleanup(); this._cleanup = null; }
211
+ const body = this.body;
212
+ const footer = this.footer;
213
+ const actions = this.headerActions;
214
+ body.innerHTML = '';
215
+ body.style.padding = ''; body.style.overflow = ''; body.style.height = '';
216
+ footer.innerHTML = '';
217
+ if (actions) actions.innerHTML = '';
218
+ const cleanup = this._handler(body, footer, actions);
219
+ if (typeof cleanup === 'function') this._cleanup = cleanup;
220
+ }
221
+
222
+ close() {
223
+ if (typeof this._cleanup === 'function') { this._cleanup(); this._cleanup = null; }
224
+ if (this._escHandler) {
225
+ document.removeEventListener('keydown', this._escHandler);
226
+ this._escHandler = null;
227
+ }
228
+ this.dispatchEvent(new CustomEvent('sol-close', { bubbles: true, composed: true }));
229
+ if (this._onClose) this._onClose();
230
+ if (this._triggerMode) {
231
+ this._handler = null;
232
+ this._renderTrigger();
233
+ } else {
234
+ this.remove();
235
+ }
236
+ }
237
+
238
+ _render() {
239
+ const s = this.shadowRoot;
240
+ s.innerHTML = `
241
+ <div class="modal-overlay">
242
+ <div class="modal" role="dialog" aria-label="${this.modalTitle}">
243
+ <div class="modal-header">
244
+ <span class="modal-title">${this.modalTitle}</span>
245
+ <div class="modal-header-actions"></div>
246
+ <button class="modal-close">\u2715</button>
247
+ </div>
248
+ <div class="modal-body"></div>
249
+ <div class="modal-footer"></div>
250
+ </div>
251
+ </div>`;
252
+ s.adoptedStyleSheets = [];
253
+ adopt(s, { sheet: MODAL_SHEET, css: CSS, extra: this._extraStyles });
254
+
255
+ s.querySelector('.modal-close').onclick = () => this.close();
256
+ s.querySelector('.modal-overlay').addEventListener('click', (e) => {
257
+ if (e.target === s.querySelector('.modal-overlay')) this.close();
258
+ });
259
+
260
+ this._escHandler = (e) => { if (e.key === 'Escape') this.close(); };
261
+ document.addEventListener('keydown', this._escHandler);
262
+ }
263
+
264
+ disconnectedCallback() {
265
+ if (this._escHandler) {
266
+ document.removeEventListener('keydown', this._escHandler);
267
+ this._escHandler = null;
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Static prompt dialog. Returns user input or null.
273
+ * @param {string} message
274
+ * @param {string} placeholder
275
+ * @returns {Promise<string|null>}
276
+ */
277
+ static prompt(message, placeholder = '') {
278
+ return new Promise(resolve => {
279
+ let settled = false;
280
+ const finish = (v) => { if (settled) return; settled = true; resolve(v); };
281
+ const m = document.createElement('sol-modal');
282
+ m.setAttribute('size', 'small');
283
+ m.modalTitle = message;
284
+ m.handler = (body, footer) => {
285
+ const input = document.createElement('input');
286
+ input.className = 'modal-input';
287
+ input.type = 'text';
288
+ input.placeholder = placeholder;
289
+ body.style.padding = '16px 20px';
290
+ body.appendChild(input);
291
+
292
+ const ok = document.createElement('button');
293
+ ok.className = 'sol-btn sol-btn-sm sol-btn-primary';
294
+ ok.textContent = 'OK';
295
+ const cancel = document.createElement('button');
296
+ cancel.className = 'sol-btn sol-btn-sm';
297
+ cancel.textContent = 'Cancel';
298
+ footer.appendChild(cancel);
299
+ footer.appendChild(ok);
300
+
301
+ const done = (v) => { m.onClose = null; m.close(); finish(v); };
302
+ ok.onclick = () => done(input.value.trim());
303
+ cancel.onclick = () => done(null);
304
+ input.onkeydown = (e) => {
305
+ if (e.key === 'Enter') done(input.value.trim());
306
+ if (e.key === 'Escape') done(null);
307
+ };
308
+ setTimeout(() => input.focus(), 50);
309
+ };
310
+ m.onClose = () => finish(null);
311
+ m.open();
312
+ });
313
+ }
314
+
315
+ /**
316
+ * Static choice dialog. Renders a message (optionally with extra
317
+ * body content) and a row of buttons; resolves with the chosen
318
+ * button's `value` (or null if dismissed via Esc / overlay / X).
319
+ *
320
+ * const pick = await SolModal.choice({
321
+ * title: 'Transfer "foo.ttl"',
322
+ * message: 'Move (delete original) or copy (keep original)?',
323
+ * buttons: [
324
+ * { label: 'Cancel', value: null },
325
+ * { label: 'Copy', value: 'copy' },
326
+ * { label: 'Move', value: 'move', primary: true },
327
+ * ],
328
+ * // optional: extra body content
329
+ * render: (body) => { ... },
330
+ * size: 'small',
331
+ * });
332
+ *
333
+ * Guarantees the promise resolves exactly once, even if the user
334
+ * clicks a button and the close handler also fires.
335
+ *
336
+ * @param {object} opts
337
+ * @param {string} opts.title
338
+ * @param {string=} opts.message
339
+ * @param {Array<{label:string, value:*, primary?:boolean}>} opts.buttons
340
+ * @param {(body:HTMLElement) => void} [opts.render]
341
+ * @param {string=} opts.size - 'small' | 'large' (default 'small')
342
+ * @returns {Promise<*>}
343
+ */
344
+ static choice({ title, message, buttons, render, size = 'small' } = {}) {
345
+ return new Promise(resolve => {
346
+ let settled = false;
347
+ const finish = (v) => { if (settled) return; settled = true; resolve(v); };
348
+ const m = document.createElement('sol-modal');
349
+ m.setAttribute('size', size);
350
+ m.modalTitle = title || '';
351
+ m.handler = (body, footer) => {
352
+ body.style.padding = '16px 20px';
353
+ if (message) {
354
+ const p = document.createElement('p');
355
+ p.style.margin = '0 0 8px';
356
+ p.textContent = message;
357
+ body.appendChild(p);
358
+ }
359
+ if (typeof render === 'function') render(body);
360
+
361
+ for (const btn of buttons || []) {
362
+ const el = document.createElement('button');
363
+ el.className = 'sol-btn sol-btn-sm' + (btn.primary ? ' sol-btn-primary' : '');
364
+ el.textContent = btn.label;
365
+ el.onclick = () => { m.onClose = null; m.close(); finish(btn.value); };
366
+ footer.appendChild(el);
367
+ }
368
+ };
369
+ m.onClose = () => finish(null);
370
+ m.open();
371
+ });
372
+ }
373
+ }
374
+
375
+ define('sol-modal', SolModal);
376
+ export { SolModal };
377
+ export default SolModal;
@@ -0,0 +1,17 @@
1
+ // sol-pod-extras.js — sol-pod's companions combined into one drop-in.
2
+ //
3
+ // sol-pod-ops (file-operations panel) and sol-wac (WAC/ACL editor) are the
4
+ // "document with pod" companions: sol-pod reaches them via customElements.get
5
+ // when present. Neither is useful on its own, so they ship together here
6
+ // rather than as two separate files. Load alongside sol-pod.umd; pod and
7
+ // sol-live-edit each ship standalone.
8
+ //
9
+ // UMD build: rdflib/dompurify/marked stay external globals (shared with the
10
+ // other pod-family UMDs on the page — no duplication).
11
+
12
+ import './sol-pod-ops.js';
13
+ import './sol-wac.js';
14
+
15
+ // Surface the JS API on `window.SolPodExtras.*`.
16
+ export { SolPodOps } from './sol-pod-ops.js';
17
+ export { SolWac } from './sol-wac.js';