From 91c818523daaad7fc87e8b873772bccb3dc3749d Mon Sep 17 00:00:00 2001 From: Sam Willis Date: Wed, 7 Aug 2024 16:15:49 +0100 Subject: [PATCH] Address feedback --- docs/docs/about.md | 4 ++-- docs/docs/api.md | 37 +++++++++++++++++----------------- docs/docs/filesystems.md | 2 +- docs/docs/index.md | 4 ++-- docs/docs/live-queries.md | 14 ++++++------- docs/docs/orm-support.md | 2 +- docs/examples.md | 2 +- docs/extensions/development.md | 8 ++++---- 8 files changed, 37 insertions(+), 36 deletions(-) diff --git a/docs/docs/about.md b/docs/docs/about.md index 6f319d36f..b725632f2 100644 --- a/docs/docs/about.md +++ b/docs/docs/about.md @@ -1,6 +1,6 @@ # What is PGlite -PGlite is a WASM Postgres build packaged into a TypeScript/JavaScript client library, that enables you to run Postgres in the browser, Node.js and Bun, with no need to install any other dependencies. It's under 3mb Gzipped, and has support for many [Postgres extensions](../extensions/), including [pgvector](../extensions/#pgvector). +PGlite is a [WASM](https://webassembly.org/) Postgres build packaged into a TypeScript/JavaScript client library, that enables you to run Postgres in the browser, [Node.js](https://nodejs.org/) and [Bun](https://bun.sh/), with no need to install any other dependencies. It's under 3mb Gzipped, and has support for many [Postgres extensions](../extensions/), including [pgvector](../extensions/#pgvector). Getting started with PGlite is simple: just install and import the NPM package, then create your embedded database: @@ -12,7 +12,7 @@ await db.query("select 'Hello world' as message;"); // -> { rows: [ { message: "Hello world" } ] } ``` -It can be used as an ephemeral in-memory database, or with persistence either to the file system (Node/Bun), or indexedDB (Browser). +It can be used as an ephemeral in-memory database, or with persistence either to the file system (Node/Bun), or IndexedDB (browser). Unlike previous "Postgres in the browser" projects, PGlite does not use a Linux virtual machine - it is simply Postgres in WASM. diff --git a/docs/docs/api.md b/docs/docs/api.md index 22d0d8f14..abf85305f 100644 --- a/docs/docs/api.md +++ b/docs/docs/api.md @@ -6,47 +6,48 @@ outline: [2, 3] ## Main Constructor -`new PGlite(dataDir: string, options: PGliteOptions)`
-`new PGlite(options: PGliteOptions)` - -A new PGlite instance is created using the `new PGlite()` constructor. - -This is imported as: +The main constructor is imported as: ```ts import { PGlite } from "@electric-sql/pglite"; ``` +The preferred way to create a PGlite instance is with the `PGlite.create()` static method that returns a promise, resolving to the new PGlite instance. + `await PGlite.create(dataDir: string, options: PGliteOptions)`
`await PGlite.create(options: PGliteOptions)` -There is also a `PGlite.create()` static method that returns a promise, resolving to the new PGlite instance. There are a couple of advantages to using the static method: +There are a couple of advantages to using the static method: + +- This awaits the [`.waitReady`](#waitready) promise, ensuring that the database has been fully initialised. +- When using TypeScript and extensions, the returned PGlite instance will have the extensions namespace on its type. This is not possible with the standard constructor due to TypesScript limitations. -- This awaits the [`.waitReady`](#waitready) promise, ensuring that the database has fully initiated. -- When using TypeScript and extensions, the returned PGlite instance will have the extensions namespace on its type. This is not possible with the standard constructor due to limitation with TypeScript. +A new PGlite instance can also be created using the `new PGlite()` constructor. +`new PGlite(dataDir: string, options: PGliteOptions)`
+`new PGlite(options: PGliteOptions)` #### `dataDir` -Path to the directory for storing the Postgres database. You can provide a url scheme for various storage backends: +Path to the directory for storing the Postgres database. You can provide a URI scheme for various storage backends: - `file://` or unprefixed
File system storage, available in Node and Bun. - `idb://`
- IndexedDB storage, available in the browser. + [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) storage, available in the browser. - `memory://`
In-memory ephemeral storage, available in all platforms. #### `options` - `dataDir: string`
- The directory to store the Postgres database in when not provided as the first argument. + The directory in which to store the Postgres database when not provided as the first argument. - `debug: 1-5`
the Postgres debug level. Logs are sent to the console. - `relaxedDurability: boolean`
- Under relaxed durability mode, PGlite will not wait for flushes to storage to complete after each query before returning results. This is particularly useful when using the indexedDB file system. + Under relaxed durability mode, PGlite will not wait for flushes to storage to complete after each query before returning results. This is particularly useful when using the IndexedDB file system. - `fs: Filesystem`
- The alternative to providing a dataDir with a filesystem prefix is to initiate the Filesystem yourself and provide it here. See [Filesystems](./filesystems.md) + The alternative to providing a dataDir with a filesystem prefix is to initialise a `Filesystem` yourself and provide it here. See [Filesystems](./filesystems.md) - `loadDataDir: Blob | File`
A tarball of a PGlite `datadir` to load when the database starts. This should be a tarball produced from the related [`.dumpDataDir()`](#dumpdatadir) method. - `extensions: Extensions`
@@ -56,7 +57,7 @@ Path to the directory for storing the Postgres database. You can provide a url s PGlite and Postgres extensions are loaded into a PGLite instance on start, and can include both a WASM build of a Postgres extension and/or a PGlite client plugin. -The `options.extensions` parameter is an object of `namespace: extension` parings. The namespace if used to expose the PGlite client plugin included in the extension. An example of this is the [live queries](./live-queries.md) extension. +The `options.extensions` parameter is an object of `namespace: extension` parings. The namespace is used to expose the PGlite client plugin included in the extension. An example of this is the [live queries](./live-queries.md) extension. ```ts import { PGlite } from "@electric-sql/pglite"; @@ -106,7 +107,7 @@ The `query` and `exec` methods take an optional `options` objects with the follo - `rowMode: "object" | "array"`
The returned row object type, either an object of `fieldName: value` mappings or an array of positional values. Defaults to `"object"`. - `parsers: ParserOptions`
- An object of type `{[[pgType: number]: (value: string) => any;]}` mapping Postgres data type id to parser function. + An object of type `{[[pgType: number]: (value: string) => any;]}` mapping Postgres data type IDs to parser functions. For convenience, the `pglite` package exports a constant for most common Postgres types: ```ts @@ -130,7 +131,7 @@ The `query` and `exec` methods take an optional `options` objects with the follo Execute one or more statements. *(note that parameters are not supported)* -This is useful for applying database migrations, or running multi-statement sql that doesn't use parameters. +This is useful for applying database migrations, or running multi-statement SQL that doesn't use parameters. Uses the *simple query* Postgres wire protocol. @@ -280,7 +281,7 @@ Query methods will wait for the `waitReady` promise to resolve if called before Result objects have the following properties: - `rows: Row[]`
- The rows retuned by the query + The rows retuned by the query. - `affectedRows?: number`
Count of the rows affected by the query. Note, this is *not* the count of rows returned, it is the number or rows in the database changed by the query. diff --git a/docs/docs/filesystems.md b/docs/docs/filesystems.md index d17ede04b..20a24712c 100644 --- a/docs/docs/filesystems.md +++ b/docs/docs/filesystems.md @@ -58,7 +58,7 @@ To use the Node FS you can use one of these methods: ## IndexedDB FS -The IndexedDB FS persists the database to IndexedDB in the browser. It's a layer over the in-memory filesystem, loading all files for the database into memory on start, and flushing them to IndexedDB after each query if they have changed. +The [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) FS persists the database to IndexedDB in the browser. It's a layer over the in-memory filesystem, loading all files for the database into memory on start, and flushing them to IndexedDB after each query if they have changed. To use the IndexedDB FS you can use one of these methods: diff --git a/docs/docs/index.md b/docs/docs/index.md index abef8ac92..41df59d6d 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -59,7 +59,7 @@ Then for an in-memory Postgres: const db = new PGlite() ``` -or to persist the database to indexedDB: +or to persist the database to IndexedDB: ```js const db = new PGlite("idb://my-pgdata"); @@ -67,7 +67,7 @@ const db = new PGlite("idb://my-pgdata"); ## Making a query -There are two methods for querying the database, `.query` and `.exec`. The former supports parameters, and the latter, multiple statements. +There are two methods for querying the database, `.query` and `.exec`. The former supports parameters, while the latter supports multiple statements. First, let's create a table and insert some test data using the `.exec` method: diff --git a/docs/docs/live-queries.md b/docs/docs/live-queries.md index 654c450ed..87e1d15f4 100644 --- a/docs/docs/live-queries.md +++ b/docs/docs/live-queries.md @@ -17,7 +17,7 @@ const pg = await PGlite.create({ There are three methods on the `live` namespace: - `live.query()` for basic live queries. With less machinery in PGlite, it's quicker for small results sets and narrow rows. -- `live.incrementalQuery()` for incremental queries. It materialises the full result set on each update from only the changes emitted by the `live.changes` api. Perfect for feeding into React, and with good performance for large result sets and wide rows. +- `live.incrementalQuery()` for incremental queries. It materialises the full result set on each update from only the changes emitted by the `live.changes` API. Perfect for feeding into React, and with good performance for large result sets and wide rows. - `live.changes()` a lower level API that emits the changes (insert/update/delete) that can then be mapped to mutations in a UI or other datastore. ## live.query @@ -54,7 +54,7 @@ Internally it watches the tables that the query depends on, and reruns the query Similar to above, but maintains a temporary table of the previous state inside of Postgres. When the tables it depends on change, the query is re-run and diffed with the last state. Only the changes from the last version of the query are copied from WASM into JS. -It requires an additional `key` argument - the name of a column (often a primary key) to key the diff on. +It requires an additional `key` argument - the name of a column (often a primary key) on which to key the diff. ```ts const ret = pg.live.incrementalQuery( @@ -71,7 +71,7 @@ The returned value is of the same type as the `query` method above. `live.changes()` -A lower-level API which is the backend for the `incrementalQuery`, it emits the changes that have occurred. It requires a `key` to key the diff on: +A lower-level API which is the backend for the `incrementalQuery`, it emits the changes that have occurred. It requires a `key` on which to compare row differences: ```ts const ret = pg.live.changes( @@ -82,7 +82,7 @@ const ret = pg.live.changes( ); ``` -the returned value from the call is defined by this interface: +The returned value from the call is defined by this interface: ```ts interface LiveChangesReturn { @@ -119,8 +119,8 @@ type Change = ChangeInsert | ChangeDelete | ChangeUpdate; Each `Change` includes the new values along with: -- `__changed_columns__` the column names that were changed -- `__op__` the operation that is required to update the state (`INSERT`, `UPDATE`, `DELETE`) -- `__after__` the `key` of the row that this row should be positioned after; it will be included in `__changed_columns__` if it has been changed. This allows for very efficient moves within an ordered set of results. +- `__changed_columns__` the column names that were changed. +- `__op__` the operation that is required to update the state (`INSERT`, `UPDATE`, `DELETE`). +- `__after__` the `key` of the row after which _this_ row should be positioned; it will be included in `__changed_columns__` if it has been changed. This allows for very efficient moves within an ordered set of results. This API can be used to implement very efficient in-place DOM updates. diff --git a/docs/docs/orm-support.md b/docs/docs/orm-support.md index bd4a1c6f3..6682a9f7c 100644 --- a/docs/docs/orm-support.md +++ b/docs/docs/orm-support.md @@ -2,7 +2,7 @@ ## Drizzle -[Drizzle](https://orm.drizzle.team) is a TypeScript ORM with support for many databases include PGlite. Features include: +[Drizzle](https://orm.drizzle.team) is a TypeScript ORM with support for many databases, including PGlite. Features include: - A declarative relational query API - An SQL-like query builder API diff --git a/docs/examples.md b/docs/examples.md index 871d4930b..f4930dd55 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -24,7 +24,7 @@ We have a number of examples showing how to use PGlite along with its capabiliti Reactivity example using the live query extensions `.live.incrementalQuery()` method. - Notify and Listen
- Example showing the use of the `NOTIFY` and `LISTEN` Postgres commands via the PGlite `.listen()` api. + Example showing the use of the `NOTIFY` and `LISTEN` Postgres commands via the PGlite `.listen()` API. - OPFS VFS
An example demonstrating the [OPFS Access Handle Pool VFS](./docs/filesystems.md#opfs-ahp-fs). diff --git a/docs/extensions/development.md b/docs/extensions/development.md index 73bf2633e..8e3a31112 100644 --- a/docs/extensions/development.md +++ b/docs/extensions/development.md @@ -36,11 +36,11 @@ export interface ExtensionSetupResult { `setup` is a function that receives the following parameters, and returns a promise that resolves to an object conforming to `ExtensionSetupResult`: - `pg`
- the [PGlite](../docs/api.md) instance that the extension is being added to + The [PGlite](../docs/api.md) instance that the extension is being added to - `emscriptenOpts`
- the options currently configured to pass to the [Emscrption Module factory](https://emscripten.org/docs/api_reference/module.html), including the [Emscript FS](https://emscripten.org/docs/api_reference/Filesystem-API.html). + The options currently configured to pass to the [Emscrption Module factory](https://emscripten.org/docs/api_reference/module.html), including the [Emscript FS](https://emscripten.org/docs/api_reference/Filesystem-API.html). - `clientOnly`
- A boolean indicating if this instance of the extension is "client only", meaning that it is on the main thread and doesn't have direct access to the underlying WASM as it is running in a worker. When true `emscriptenOpts` and `bundlePath` should not re returned as they will have no effect. + A boolean indicating if this instance of the extension is "client only", meaning that it is on the main thread and doesn't have direct access to the underlying WASM as it is running in a worker. When true, `emscriptenOpts` and `bundlePath` should not re returned as they will have no effect. The returned object has these properties - all are optional: @@ -51,7 +51,7 @@ The returned object has these properties - all are optional: - `bundlePath`
The path to the Postgres extension tarball - see [Building Postgres Extensions](#building-postgres-extensions) - `init`
- An initiation function that will be run after the PGlite instance and Postgres runtime has started, but before the instance is marked as ready for external usage. You can use this to perform any initiation your extension needs to perform on the database at startup. + An initialisation function that will be run after the PGlite instance and Postgres runtime has started, but before the instance is marked as ready for external usage. You can use this to perform any initialisation your extension needs to perform on the database at startup. - `close`
A function that will be called when the user calls `close()` on their PGlite instance; this is called before the database has been shut down.