@riebeckite/plugin-vega-lite 0.0.31 → 0.0.33

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/README.md CHANGED
@@ -54,6 +54,20 @@ Put a Vega-Lite specification as JSON in the body of the code block. Both
54
54
  The caption comes from the code-block `title`, or from the specification's
55
55
  `title`.
56
56
 
57
+ ## Live example
58
+
59
+ ~~~vega-lite
60
+ {
61
+ "title": "Revenue",
62
+ "data": { "values": [{ "category": "A", "value": 28 }, { "category": "B", "value": 55 }] },
63
+ "mark": "bar",
64
+ "encoding": {
65
+ "x": { "field": "category", "type": "nominal" },
66
+ "y": { "field": "value", "type": "quantitative" }
67
+ }
68
+ }
69
+ ~~~
70
+
57
71
  ## How it renders
58
72
 
59
73
  A ` ```vega-lite ` block becomes a `figure.rb-vega-lite`:
@@ -110,7 +124,7 @@ JavaScript is disabled and the spec stays readable in the fallback `details`.
110
124
 
111
125
  ## Main exports
112
126
 
113
- - `vegaLite(options?)`: create the plugin (`vegaLitePlugin` is an alias)
127
+ - `vegaLite(options?)`: create the plugin (`vegaLite` is an alias)
114
128
  - `initVegaLite`: initialize client-side rendering
115
129
  - Types: `VegaLiteOptions`, `VegaLiteSpec`, `VegaLiteTheme`,
116
130
  `VegaLiteRenderer`
package/README_ja.md CHANGED
@@ -51,7 +51,21 @@ export default defineConfig({
51
51
 
52
52
  キャプションにはコードブロックの `title`、なければ仕様の `title` を使います。
53
53
 
54
- ## どのように描画されるか
54
+ ## 実行例
55
+
56
+ ~~~vega-lite
57
+ {
58
+ "title": "Revenue",
59
+ "data": { "values": [{ "category": "A", "value": 28 }, { "category": "B", "value": 55 }] },
60
+ "mark": "bar",
61
+ "encoding": {
62
+ "x": { "field": "category", "type": "nominal" },
63
+ "y": { "field": "value", "type": "quantitative" }
64
+ }
65
+ }
66
+ ~~~
67
+
68
+ ## 描画の仕組み
55
69
 
56
70
  ` ```vega-lite ` のコードブロックは `figure.rb-vega-lite` に置き換わります。
57
71
 
@@ -62,7 +76,7 @@ export default defineConfig({
62
76
 
63
77
  `initVegaLite` は `[data-vega-lite]` を探し、`data-vega-lite-spec` を `JSON.parse` してから `vega`、`vega-lite`、`vega-embed` を動的インポートして `vega-embed` で描画します。描画に成功すると `data-vega-lite="rendered"` になります。
64
78
 
65
- `vega-embed` の読み込み、仕様の `JSON.parse`、描画のいずれかが失敗した場合は例外を投げず、その figure の `details` を開いて元の仕様を見せます(`data-vega-lite="error"`)。
79
+ `vega-embed` の読み込み、仕様の `JSON.parse`、描画のいずれかが失敗した場合は例外を投げず、その `<figure>` の `details` を開いて元の仕様を見せます(`data-vega-lite="error"`)。
66
80
 
67
81
  JSON を解析できないコードブロックは置き換えず、通常のコードブロックのまま残し、`@riebeckite/plugin-vega-lite` を `source` に持つ診断を出します。
68
82
 
@@ -74,13 +88,13 @@ JSON を解析できないコードブロックは置き換えず、通常のコ
74
88
  | `actions` | `null` | `vega-embed` の操作メニューを表示する(`true` / `false` / `null`) |
75
89
  | `theme` | `"light"` | 配色(`"light"`、`"dark"`、`"none"`) |
76
90
  | `renderer` | `"canvas"` | Vega のレンダラー(`"canvas"` または `"svg"`) |
77
- | `className` | `"rb-vega-lite"` | figure に付ける基準クラス |
91
+ | `className` | `"rb-vega-lite"` | `<figure>` に付ける基準クラス |
78
92
 
79
93
  `actions` が `null` のときは `vega-embed` の既定(操作メニューあり)に従います。`theme` が `"light"` または `"none"` のときは Vega 既定の明るい配色を使い、`"dark"` のときだけ `vega-embed` の `dark` テーマを適用します。
80
94
 
81
95
  ## クライアント側の描画
82
96
 
83
- クライアントの初期化コードは静的なので、プラグインのオプションは受け取りません。`actions`、`theme`、`renderer` は figure の `data-vega-lite-*` 属性に埋め込まれ、`initVegaLite` がそこから読み取ります。
97
+ クライアントの初期化コードは静的なので、プラグインのオプションは受け取りません。`actions`、`theme`、`renderer` は `<figure>` の `data-vega-lite-*` 属性に埋め込まれ、`initVegaLite` がそこから読み取ります。
84
98
 
85
99
  Vega ランタイムは `import()` で動的に読み込むため、JavaScript を無効にしていてもページは表示され、仕様はフォールバックの `details` から読めます。
86
100
 
@@ -94,7 +108,7 @@ Vega ランタイムは `import()` で動的に読み込むため、JavaScript
94
108
 
95
109
  ## 主なエクスポート
96
110
 
97
- - `vegaLite(options?)`: プラグインを作成する(`vegaLitePlugin` は別名)
111
+ - `vegaLite(options?)`: プラグインを作成する(`vegaLite` は別名)
98
112
  - `initVegaLite`: クライアント側の描画を初期化する
99
113
  - 型: `VegaLiteOptions`、`VegaLiteSpec`、`VegaLiteTheme`、`VegaLiteRenderer`
100
114
 
package/dist/client.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ type ClientContext = {
2
+ root?: ParentNode;
3
+ signal?: AbortSignal;
4
+ };
1
5
  /**
2
6
  * Renders every server-emitted `[data-vega-lite]` figure in the browser.
3
7
  *
@@ -6,4 +10,5 @@
6
10
  * `<details>`) when JavaScript is disabled. A broken payload or a Vega error
7
11
  * reveals the fallback for that figure without affecting the rest of the page.
8
12
  */
9
- export declare function initVegaLite(): Promise<void>;
13
+ export declare function initVegaLite(context?: ClientContext): Promise<undefined | (() => void)>;
14
+ export {};
package/dist/client.js CHANGED
@@ -1,9 +1,10 @@
1
1
  // client.ts
2
2
  var FIGURE_SELECTOR = "[data-vega-lite]";
3
3
  var CANVAS_SELECTOR = "[data-vega-lite-canvas]";
4
- async function initVegaLite() {
4
+ async function initVegaLite(context = {}) {
5
+ const root = context.root ?? document;
5
6
  const figures = Array.from(
6
- document.querySelectorAll(FIGURE_SELECTOR)
7
+ root.querySelectorAll(FIGURE_SELECTOR)
7
8
  );
8
9
  if (figures.length === 0) return;
9
10
  let embed;
@@ -18,33 +19,46 @@ async function initVegaLite() {
18
19
  for (const figure of figures) revealFallback(figure);
19
20
  return;
20
21
  }
22
+ if (context.signal?.aborted) return;
23
+ const views = [];
21
24
  for (const figure of figures) {
22
- await renderFigure(embed, figure);
25
+ if (context.signal?.aborted || !figure.isConnected) return;
26
+ const view = await renderFigure(embed, figure, context.signal);
27
+ if (view) views.push(view);
23
28
  }
29
+ return () => {
30
+ for (const view of views) view.finalize();
31
+ };
24
32
  }
25
- async function renderFigure(embed, figure) {
33
+ async function renderFigure(embed, figure, signal) {
26
34
  const canvas = figure.querySelector(CANVAS_SELECTOR);
27
35
  const serialized = figure.dataset.vegaLiteSpec;
28
36
  if (!canvas || !serialized) {
29
37
  revealFallback(figure);
30
- return;
38
+ return void 0;
31
39
  }
32
40
  let spec;
33
41
  try {
34
42
  spec = JSON.parse(serialized);
35
43
  } catch {
36
44
  revealFallback(figure);
37
- return;
45
+ return void 0;
38
46
  }
39
47
  try {
40
- await embed(
48
+ const result = await embed(
41
49
  canvas,
42
50
  spec,
43
51
  buildEmbedOptions(figure)
44
52
  );
53
+ if (signal?.aborted || !figure.isConnected) {
54
+ result.view.finalize();
55
+ return void 0;
56
+ }
45
57
  figure.dataset.vegaLite = "rendered";
58
+ return result.view;
46
59
  } catch {
47
60
  revealFallback(figure);
61
+ return void 0;
48
62
  }
49
63
  }
50
64
  function buildEmbedOptions(figure) {
package/dist/index.d.ts CHANGED
@@ -7,5 +7,3 @@ export type { VegaLiteOptions, VegaLiteRenderer, VegaLiteSpec, VegaLiteTheme, }
7
7
  * `initVegaLite`, which imports the Vega runtime dynamically.
8
8
  */
9
9
  export declare function vegaLite(options?: VegaLiteOptions): import("@riebeckite/core").RiebeckitePlugin<VegaLiteOptions>;
10
- /** Alias kept for symmetry with the other plugin factories. */
11
- export declare const vegaLitePlugin: typeof vegaLite;
package/dist/index.js CHANGED
@@ -6,50 +6,20 @@ import {
6
6
  } from "@riebeckite/core";
7
7
 
8
8
  // src/hast.ts
9
- function visitElements(node, visitor, parent, index) {
10
- if (isElementNode(node)) visitor(node, parent, index);
11
- for (const [childIndex, child] of [...getChildren(node)].entries()) {
12
- visitElements(
13
- child,
14
- visitor,
15
- hasChildren(node) ? node : parent,
16
- childIndex
17
- );
18
- }
19
- }
20
- function element(tagName, properties = {}, children = []) {
21
- return { type: "element", tagName, properties, children };
22
- }
23
- function text(value) {
24
- return { type: "text", value };
25
- }
26
- function getTextContent(node) {
27
- if (node.type === "text" && "value" in node && typeof node.value === "string") {
28
- return node.value;
29
- }
30
- return getChildren(node).map(getTextContent).join("");
31
- }
32
- function getStringProperty(node, key) {
33
- const value = node.properties?.[key];
34
- if (typeof value === "string") return value;
35
- if (Array.isArray(value)) return value.join(" ");
36
- return null;
37
- }
38
- function hasClass(node, className) {
39
- const value = node.properties?.className;
40
- const classes = Array.isArray(value) ? value.map(String) : typeof value === "string" ? value.split(/\s+/) : [];
41
- return classes.includes(className);
42
- }
43
- function isElementNode(node) {
44
- return node.type === "element";
45
- }
46
- function hasChildren(node) {
47
- return Array.isArray(node.children);
48
- }
49
- function getChildren(node) {
50
- const children = node.children;
51
- return Array.isArray(children) ? children : [];
52
- }
9
+ import {
10
+ element as sharedElement,
11
+ getStringProperty as sharedGetStringProperty,
12
+ getTextContent as sharedGetTextContent,
13
+ hasClass as sharedHasClass,
14
+ text as sharedText,
15
+ visitElements as sharedVisitElements
16
+ } from "@riebeckite/diagram";
17
+ var element = sharedElement;
18
+ var text = sharedText;
19
+ var getTextContent = sharedGetTextContent;
20
+ var getStringProperty = sharedGetStringProperty;
21
+ var hasClass = sharedHasClass;
22
+ var visitElements = sharedVisitElements;
53
23
 
54
24
  // src/rehype.ts
55
25
  var DEFAULT_CLASS_NAME = "rb-vega-lite";
@@ -117,7 +87,7 @@ function buildFigure(input) {
117
87
  );
118
88
  }
119
89
  children.push(
120
- element("details", { className: `${base}__fallback` }, [
90
+ element("details", { className: `${base}__fallback rb-source-fallback` }, [
121
91
  element("summary", {}, [text("Vega-Lite spec")]),
122
92
  element("pre", {}, [element("code", {}, [text(input.source)])])
123
93
  ])
@@ -210,12 +180,14 @@ function vegaLite(options = {}) {
210
180
  createClientEntry(
211
181
  "vega-lite",
212
182
  "@riebeckite/plugin-vega-lite/client",
213
- "initVegaLite"
183
+ "initVegaLite",
184
+ void 0,
185
+ void 0,
186
+ "context"
214
187
  )
215
188
  ]
216
189
  });
217
190
  }
218
- var vegaLitePlugin = vegaLite;
219
191
  function validateVegaLiteOptions(options) {
220
192
  if (!options) return [];
221
193
  const issues = [];
@@ -250,6 +222,5 @@ function isRenderer(value) {
250
222
  }
251
223
  export {
252
224
  rehypeVegaLite,
253
- vegaLite,
254
- vegaLitePlugin
225
+ vegaLite
255
226
  };
@@ -1,7 +1,7 @@
1
1
  import type { ElementNode, HastNode, ParentNode, TextNode } from "./types.js";
2
- export declare function visitElements(node: HastNode, visitor: (node: ElementNode, parent?: ParentNode, index?: number) => void, parent?: ParentNode, index?: number): void;
3
- export declare function element(tagName: string, properties?: Record<string, unknown>, children?: HastNode[]): ElementNode;
4
- export declare function text(value: string): TextNode;
5
- export declare function getTextContent(node: HastNode): string;
6
- export declare function getStringProperty(node: ElementNode, key: string): string | null;
7
- export declare function hasClass(node: ElementNode, className: string): boolean;
2
+ export declare const element: (tagName: string, properties?: Record<string, unknown>, children?: HastNode[]) => ElementNode;
3
+ export declare const text: (value: string) => TextNode;
4
+ export declare const getTextContent: (node: HastNode) => string;
5
+ export declare const getStringProperty: (node: ElementNode, key: string) => string | null;
6
+ export declare const hasClass: (node: ElementNode, className: string) => boolean;
7
+ export declare const visitElements: (node: HastNode, visitor: (node: ElementNode, parent?: ParentNode, index?: number) => void, parent?: ParentNode, index?: number) => void;
@@ -32,7 +32,7 @@ export type TextNode = {
32
32
  type: "text";
33
33
  value: string;
34
34
  };
35
- export type RawNode = {
35
+ type RawNode = {
36
36
  type: "raw";
37
37
  value: string;
38
38
  };
@@ -40,3 +40,4 @@ export type HastNode = ElementNode | TextNode | RawNode | {
40
40
  type: string;
41
41
  [key: string]: unknown;
42
42
  };
43
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riebeckite/plugin-vega-lite",
3
- "version": "0.0.31",
3
+ "version": "0.0.33",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,10 +21,11 @@
21
21
  "./style.css": "./style.css"
22
22
  },
23
23
  "dependencies": {
24
+ "@riebeckite/core": "0.0.33",
25
+ "@riebeckite/diagram": "0.0.33",
24
26
  "vega": "^6.4.0",
25
27
  "vega-embed": "^7.3.0",
26
- "vega-lite": "^6.4.3",
27
- "@riebeckite/core": "0.0.31"
28
+ "vega-lite": "^6.4.3"
28
29
  },
29
30
  "publishConfig": {
30
31
  "access": "public"
package/style.css CHANGED
@@ -40,26 +40,6 @@
40
40
  height: auto;
41
41
  }
42
42
 
43
- .rb-vega-lite__fallback {
44
- border-top: 1px solid var(--rb-vega-lite-rule);
45
- color: var(--rb-vega-lite-muted);
46
- font-size: 0.8125rem;
47
- }
48
-
49
- .rb-vega-lite__fallback summary {
50
- cursor: pointer;
51
- padding: 0.5rem 0.75rem;
52
- }
53
-
54
- .rb-vega-lite__fallback pre {
55
- overflow: auto;
56
- margin: 0 1rem;
57
- padding: 0.75rem;
58
- border-top: 1px solid var(--rb-vega-lite-rule);
59
- color: var(--rb-vega-lite-ink);
60
- background: color-mix(in srgb, var(--rb-vega-lite-ink) 6%, transparent);
61
- }
62
-
63
43
  .rb-vega-lite[data-vega-lite="error"] .rb-vega-lite__canvas::before,
64
44
  .rb-vega-lite[data-vega-lite="pending"] .rb-vega-lite__canvas:empty::before {
65
45
  content: "Chart could not be rendered.";