Skip to content

Commit 97ace9c

Browse files
committed
1.1.0
1 parent 14e7132 commit 97ace9c

File tree

6 files changed

+93
-21
lines changed

6 files changed

+93
-21
lines changed

docs/databases.html

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131
**If query results are saved, how do I update them?** In Observable Desktop, you can re-run a SQL cell by clicking the **Play** button, by hitting <span style="font-family: var(--sans-serif);">**shift-return**</span>, or by clicking on the query age in the cell toolbar. In Observable Notebook Kit, delete the corresponding file from the `.observable/cache` directory; you can also use continuous deployment, such as GitHub Actions, to refresh data automatically.
3232
</script>
3333
<script id="28" type="text/markdown">
34-
**How do I configure my database?** When using DuckDB or (localhost) Postgres with the default settings, no configuration is required; simply specify `duckdb`, `postgres`, or a `.duckdb` (or `.db`) file as the **database** in the SQL cell. Note: you must save your notebook before running queries, since where you save the notebook determines which databases are accessible and where query results are saved. To configure databases, edit the <code>.observable/<wbr>databases.json</code> file alongside your notebook; see below for details. For example, if your notebooks are stored in `docs`,
34+
**How do I configure my database?** When using DuckDB, SQLite, or (localhost) Postgres with the default settings, no configuration is required; simply specify `duckdb`, `sqlite`, `postgres`, or a `.duckdb` or `.db` file as the **database** in the SQL cell. Note: you must save your notebook before running queries, since where you save the notebook determines which databases are accessible and where query results are saved. To configure databases, edit the <code>.observable/<wbr>databases.json</code> file alongside your notebook; see below for details. For example, if your notebooks are stored in `docs`,
3535
then a notebook `docs/example.html` can access any database configured in <code>docs/<wbr>.observable/<wbr>databases.json</code>. In the future, Observable Desktop will provide a built-in UI for configuring databases.
3636
</script>
3737
<script id="15" type="text/markdown">
38-
**Which databases are supported?** Currently DuckDB, Snowflake, and Postgres (PostgreSQL). The Postgres driver should also work with Postgres-compatible databases such as ClickHouse, Amazon Redshift, and Google Cloud SQL. We plan on adding more data connectors soon, notably Google BigQuery and Databricks. Our data connectors are [open-source](https://github.com/observablehq/notebook-kit/tree/main/src/databases) and we welcome contributions of additional database drivers! While you can query OLTP databases, we recommend OLAP databases because fast _ad hoc_ queries greatly accelerate analysis.
38+
**Which databases are supported?** Currently DuckDB, SQLite, Snowflake, and Postgres (PostgreSQL). The Postgres driver should also work with Postgres-compatible databases such as ClickHouse, Amazon Redshift, and Google Cloud SQL. We plan on adding more data connectors soon, notably Google BigQuery and Databricks. Our data connectors are [open-source](https://github.com/observablehq/notebook-kit/tree/main/src/databases) and we welcome contributions of additional database drivers! While you can query OLTP databases, we recommend OLAP databases because fast _ad hoc_ queries greatly accelerate analysis.
3939
</script>
4040
<script id="35" type="text/markdown">
4141
**How do I query my database?** Insert a new cell, say by clicking the <b>+</b> button between cells. Convert the new cell to SQL by hitting down or <span style="font-family: var(--sans-serif);">⌘4</span>. By default, SQL cells query the default `duckdb` in-memory database. To query a different database, edit the **database** in the cell toolbar, then click ↩︎ or hit <span style="font-family: var(--sans-serif);">return</span>. Then refocus the SQL cell, edit your query, and hit <span style="font-family: var(--sans-serif);">shift-return</span> to run it.
@@ -151,7 +151,7 @@
151151
**What about custom database clients and DuckDB-Wasm?** If you specify a SQL's database using `var:` (such as `var:db`), you can then provide a custom database client of the given name (such as `db`) that runs in the browser. This feature is most often used with `DuckDBClient` (DuckDB-Wasm), but you can provide any object that exposes a `sql` tagged template literal.
152152
</script>
153153
<script id="10" type="text/markdown">
154-
**How do I use databases with Notebook Kit?** Database drivers come bundled with Observable Desktop, but are not installed by default with Notebook Kit. Database drivers are instead marked as optional peer dependencies, and you must install them yourself.
154+
**How do I use databases with Notebook Kit?** Database drivers come bundled with Observable Desktop, but with the exception of SQLite are not installed by default with Notebook Kit. Database drivers are instead marked as optional peer dependencies, and you must install them yourself.
155155

156156
To install the DuckDB driver:
157157

@@ -202,6 +202,18 @@
202202

203203
The **path** option stores the relative path to the DuckDB (`.duckdb`) database file; if not specified, the database will be in-memory (`:memory:`). The **options** object contains any [DuckDB configuration options](https://duckdb.org/docs/stable/configuration/overview.html).
204204
</script>
205+
<script id="64" type="text/markdown">
206+
**How do I configure SQLite?** The following options are supported:
207+
208+
```ts
209+
type SQLiteConfig = {
210+
type: "sqlite";
211+
path?: string;
212+
}
213+
```
214+
215+
The **path** option stores the relative path to the SQLite (`.db`) database file; if not specified, the database will be in-memory (`:memory:`).
216+
</script>
205217
<script id="52" type="text/markdown">
206218
**How do I configure Postgres?** The following options are supported:
207219

docs/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@
181181
```json
182182
{
183183
"dependencies": {
184-
"@observablehq/notebook-kit": "^1.0.1"
184+
"@observablehq/notebook-kit": "^%VITE_VERSION%"
185185
},
186186
"scripts": {
187187
"docs:preview": "notebooks preview --root docs",
@@ -201,7 +201,7 @@
201201
This generates a `.observable/dist` folder containing the built site, which you can then deploy to your preferred static site hosting service, such as GitHub Pages, Vercel, or Netlify.
202202
</script>
203203
<script id="46" type="text/markdown">
204-
When building notebooks, we use static generation for Markdown and HTML cells: static content is statically rendered. This improves the user experience by accelerating the first contentful paint, and by reducing reflow during page load --- your page appears instantly. It's good for SEO, too, because static content is now readable by search engines without JavaScript.
204+
When building notebooks, we use static generation for Markdown and HTML cells: static content is statically rendered. We "bake" the results of static [database queries](./databases), too. Static generation improves the user experience by accelerating the first contentful paint, and by reducing reflow during page load --- your page appears instantly. It's good for SEO, too, because static content is now readable by search engines without JavaScript.
205205
</script>
206206
<script id="19" type="text/markdown">
207207
<aside>You can also use the new Vite plugin directly if you want to integrate notebooks into your existing Vite-based application.</aside>

docs/kit.html

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
**Observable Notebook Kit** is an [open-source command-line tool](https://github.com/observablehq/notebook-kit) for building static sites from Observable Notebooks based on an open file format. Notebook Kit also includes a Vite plugin and a low-level JavaScript interface for deep integration of Observable Notebooks with custom web applications.
1111
</script>
1212
<script id="43" type="text/markdown">
13-
Notebook Kit is available as part of [**Notebooks 2.0 Technology Preview**](./), which includes **Observable Desktop**, a macOS application for editing notebooks.
13+
Notebook Kit is available as part of [**Notebooks 2.0 Technology Preview**](./), which includes [Observable Desktop](./desktop), a macOS application for editing notebooks.
1414
</script>
1515
<script id="46" type="text/markdown">
1616
For more on authoring notebooks, see the [Notebooks system guide](./system-guide).
@@ -32,7 +32,25 @@
3232
pnpm add @observablehq/notebook-kit @fontsource/inter @fontsource/source-serif-4 @fontsource/spline-sans-mono
3333
```
3434

35-
Notebook Kit requires [Node.js](https://nodejs.org/en) 20.19+ or 22.12+.
35+
If you plan on using [database connectors](./databases), you must also install the drivers for the databases you wish to use. To install the DuckDB driver:
36+
37+
```sh
38+
npm add @duckdb/node-api
39+
```
40+
41+
To install the Postgres driver:
42+
43+
```sh
44+
npm add postgres
45+
```
46+
47+
To install the Snowflake driver:
48+
49+
```sh
50+
npm add snowflake-sdk
51+
```
52+
53+
Notebook Kit requires [Node.js](https://nodejs.org/en) 20.19+ or 22.12+. To use the SQLite database connector, you must use Node.js 24+. [Bun](https://bun.com/) 1.2+ should also work, but is not officially supported.
3654
</script>
3755
<script id="47" type="text/markdown">
3856
---
@@ -123,7 +141,7 @@ <h1>Hello, <i>world</i>!</h1>
123141
A SQL (`application/sql`) cell:
124142

125143
```html
126-
<script type="application/sql" database="reporting">
144+
<script type="application/sql" database="reporting" output="customers">
127145
SELECT * FROM customers
128146
<\/script>
129147
```
@@ -227,15 +245,15 @@ <h1>Hello, <i>world</i>!</h1>
227245

228246
## Command-line interface
229247

230-
Notebook Kit's CLI supports three commands: `preview` for a live preview of notebooks, `build` for building a static site, and `download` for downloading Observable Notebooks as HTML.
248+
Notebook Kit's CLI supports four commands: `preview` for a live preview of notebooks, `build` for building a static site, `download` for downloading Observable Notebooks as HTML, and `query` for saving the results of database queries.
231249
</script>
232250
<script id="71" type="text/markdown">
233251
We recommend that you install Notebook Kit locally to a project using a package manager such as npm, and then add preview and build scripts to your `package.json`.
234252

235253
```json
236254
{
237255
"dependencies": {
238-
"@observablehq/notebook-kit": "^1.0.1"
256+
"@observablehq/notebook-kit": "^%VITE_VERSION%"
239257
},
240258
"scripts": {
241259
"docs:preview": "notebooks preview --root docs",
@@ -283,6 +301,15 @@ <h1>Hello, <i>world</i>!</h1>
283301
notebooks download https://observablehq.com/@d3/bar-chart > docs/bar-chart.html
284302
```
285303
</script>
304+
<script id="76" type="text/markdown">
305+
### Query
306+
307+
Run the `query` command to save the result of a [database query](./databases). (This is typically done automatically, but can be used to prepare or refresh queries manually.) Pass positional arguments to interpolate JSON-encoded values into the query.
308+
309+
```sh
310+
notebooks query --database duckdb 'SELECT 1 + ' '2'
311+
```
312+
</script>
286313
<script id="6" type="text/markdown">
287314
---
288315

@@ -296,14 +323,14 @@ <h1>Hello, <i>world</i>!</h1>
296323
The Vite plugin is recommended for Vite-based applications.
297324
</script>
298325
<script id="42" type="text/markdown">
299-
#### <code class="language-ts">observable({template?: string}): PluginOption</code>
326+
#### <code class="language-ts">observable({template?: string, transformTemplate?: (template: string) => string | Promise&lt;string&gt;, transformNotebook?: (notebook: Notebook) => Notebook | Promise&lt;Notebook&gt;}, window?: Window, parser?: DOMParser): PluginOption</code>
300327

301328
Returns a Vite plugin for rendering notebook HTML as vanilla HTML. Markdown and HTML cells are rendered statically (without any interpolated dynamic values), and then, if needed, replaced with dynamic content when the page loads. Other cell modes are exclusively dynamic. Pinned cells display their source code statically rendered below any output. Supported languages are syntax-highlighted using Lezer.
302329
</script>
303330
<script id="41" type="text/markdown">
304331
#### <code class="language-ts">config(): UserConfig</code>
305332

306-
Returns the base Vite config needed to use the `observable()` Vite plugin; this enables top-level await and adds resolvers for `npm:`, `jsr:`, and `observable:` import protocols.
333+
Returns the base Vite config needed to use the `observable()` Vite plugin; this enables top-level await, multi-page application behavior, and adds resolvers for `npm:`, `jsr:`, and `observable:` import protocols.
307334
</script>
308335
<script id="17" type="text/markdown">
309336
### Build API
@@ -326,19 +353,19 @@ <h1>Hello, <i>world</i>!</h1>
326353
Parses the specified template cell source code (such as the contents of a Markdown or SQL cell), returning the resulting AST as a `TemplateLiteral`. (This method is called internally by `transpile`.)
327354
</script>
328355
<script id="22" type="text/markdown">
329-
#### <code class="language-ts">transpile(input: string, mode: Cell[\"mode\"], options?: TranspileOptions): TranspiledJavaScript</code>
356+
#### <code class="language-ts">transpile(input: Cell, options?: TranspileOptions): TranspiledJavaScript</code>
330357

331-
Transpiles the specified cell source code, given the cell's `mode`. The transpiled source is returned as a `body` function suitable for use with [`variable.define`](https://github.com/observablehq/runtime/blob/main/README.md#variabledefinename-inputs-definition) from the Observable Runtime, along with any named `inputs` (unbound references) and `outputs` (top-level declarations).
358+
Transpiles the specified cell. The transpiled source is returned as a `body` function suitable for use with [`variable.define`](https://github.com/observablehq/runtime/blob/main/README.md#variabledefinename-inputs-definition) from the Observable Runtime, along with any named `inputs` (unbound references) and `outputs` (top-level declarations).
332359
</script>
333360
<script id="23" type="text/markdown">
334361
#### <code class="language-ts">transpileJavaScript(input: string, options?: TranspileOptions): TranspiledJavaScript</code>
335362

336363
Transpiles the specified JavaScript cell source code. The transpiled source is returned as a `body` function suitable for use with [`variable.define`](https://github.com/observablehq/runtime/blob/main/README.md#variabledefinename-inputs-definition) from the Observable Runtime, along with any named `inputs` (unbound references) and `outputs` (top-level declarations).
337364
</script>
338365
<script id="21" type="text/markdown">
339-
#### <code class="language-ts">transpileTemplate(input: string, tag = \"\", raw = false): string</code>
366+
#### <code class="language-ts">transpileTemplate(input: Cell): string</code>
340367

341-
Transpiles the specified template cell source code (such as the contents of a Markdown or SQL cell), returning the corresponding JavaScript source code consisting of a single template literal expression; the given `tag` is the source code of the template literal tag, if any (such as `md` for Markdown), and the given `raw` flag indicates whether the template literal is raw. (This method is called internally by `transpile`, and the result is passed to `transpileJavaScript`.)
368+
Transpiles the specified template cell, such as a Markdown or SQL cell, returning the corresponding JavaScript source code consisting of a single template literal expression. (This method is called internally by `transpile`, and the result is passed to `transpileJavaScript`.)
342369
</script>
343370
<script id="45" type="text/markdown">
344371
### Utility API
@@ -360,11 +387,26 @@ <h1>Hello, <i>world</i>!</h1>
360387

361388
Returns the default `pinned` value for the given cell `mode`.
362389
</script>
390+
<script id="84" type="text/markdown">
391+
#### <code class="language-ts">serialize(notebook: Notebook, {document?: Document} = {}): string</code>
392+
393+
Serializes the specified notebook to HTML.
394+
</script>
395+
<script id="85" type="text/markdown">
396+
#### <code class="language-ts">deserialize(html: string, {parser?: DOMParser} = {}): Notebook</code>
397+
398+
Deserializes the specified HTML to a notebook.
399+
</script>
363400
<script id="15" type="text/markdown">
364401
### Runtime API
365402

366403
The Runtime API provides some additional logic on top of the [Observable Runtime](https://github.com/observablehq/runtime) to run the notebook, allowing cells to be redefined at runtime, and implementing the notebook standard library, including the `display` and `view` functions which are scoped per-cell.
367404
</script>
405+
<script id="77" type="text/markdown">
406+
#### <code class="language-ts">constructor NotebookRuntime(builtins?: Record<string, unknown>)</code>
407+
408+
Instantiates a new notebook runtime, given the specified built-ins, which defaults to (the standard) `library`. The returned instance exposes a `runtime`, `main`, and `define` methods which are equivalent to those below, but scoped to this specific instance. This constructor allows multiple notebooks to be instantiated concurrently.
409+
</script>
368410
<script id="28" type="text/markdown">
369411
#### <code class="language-ts">define(state: DefineState, definition: Definition, observe?: () => Observer): void</code>
370412

@@ -420,4 +462,24 @@ <h1>Hello, <i>world</i>!</h1>
420462

421463
The built-ins provided to the runtime; the notebook standard library. This object includes the definitions for various built-ins, such as `now`, `width`, `Generators`, and `Mutable`.
422464
</script>
465+
<script id="78" type="text/markdown">
466+
### Database API
467+
468+
The Database API provides a low-level API for running [database queries](./databases).
469+
</script>
470+
<script id="81" type="text/markdown">
471+
#### <code class="language-ts"> getDatabaseConfig(sourcePath: string, databaseName: string): Promise&lt;DatabaseConfig&gt;</code>
472+
473+
Loads the database config given a path to a notebook source file and the name of a database.
474+
</script>
475+
<script id="82" type="text/markdown">
476+
#### <code class="language-ts"> getDatabase(config: DatabaseConfig): Promise&lt;QueryTemplateFunction&gt;</code>
477+
478+
Returns the query template function (equivalent to the `sql` tagged template literal) for running a query against the given database.
479+
</script>
480+
<script id="83" type="text/markdown">
481+
#### <code class="language-ts">getQueryCachePath(sourcePath: string, databaseName: string, strings: readonly string[], ...params: unknown[]): Promise&lt;string&gt;</code>
482+
483+
Returns the path to the query results cache file, given a path to a notebook source file, the name of a database, and query template parts.
484+
</script>
423485
</notebook>

docs/observable.tmpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,10 @@
117117
<div>Desktop user guide</div>
118118
<div style="opacity: 0.8; font-weight: normal; font-size: 14px;">A visual guide to editing notebooks with Observable Desktop</div>
119119
</a>
120-
<!-- a href="/notebook-kit/databases" style="color: inherit;">
120+
<a href="/notebook-kit/databases" style="color: inherit;">
121121
<div>Database connectors</div>
122122
<div style="opacity: 0.8; font-weight: normal; font-size: 14px;">Query SQL databases and data warehouses from notebooks</div>
123-
</a -->
123+
</a>
124124
</div>
125125
</div>
126126
</div>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"type": "git",
66
"url": "git+https://github.com/observablehq/notebook-kit.git"
77
},
8-
"version": "1.1.0-rc.17",
8+
"version": "1.1.0",
99
"type": "module",
1010
"scripts": {
1111
"test": "vitest",

src/databases/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import {isEnoent} from "../lib/error.js";
55
import {hash as getQueryHash, nameHash as getNameHash} from "../lib/hash.js";
66
import type {ColumnSchema, QueryParam} from "../runtime/index.js";
77

8-
export {hash as getQueryHash, nameHash as getNameHash} from "../lib/hash.js";
9-
108
export type DatabaseConfig = DuckDBConfig | SQLiteConfig | SnowflakeConfig | PostgresConfig;
119

1210
export type DuckDBConfig = {

0 commit comments

Comments
 (0)