Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ Sets the number of iterations each test uses by default.

To run tests in the browser, you first have to install playwright:

```shell
```bash
npx playwright install
```

Expand Down Expand Up @@ -349,7 +349,7 @@ Your CouchDB will most likely then run at `http://127.0.0.1:5984`. All you need

1. In the [CouchDB admin UI](http://127.0.0.1:5984/_utils), click on `Configuration` -> `CORS`.
2. Via cURL (`_local` is the node name in single-node databases, which your local dev CouchDB probably is):
```sh
```bash
curl 'http://admin:password@127.0.0.1:5984/_node/_local/_config/cors/origins' -X PUT -d '"http://127.0.0.1:8000"'
```
3. There’s also an older [npm package](https://github.com/pouchdb/add-cors-to-couchdb) to help you do this porgrammatically.
Expand All @@ -358,15 +358,15 @@ Your CouchDB will most likely then run at `http://127.0.0.1:5984`. All you need

If you’re modifying the test utils (`/tests/integration/utils.js` etc.) or adding logs to them, you need to rebuild these before running your tests again, eg.:

```sh
```bash
$ npm run build && CLIENT=firefox npm test
```

### Flaky tests and random timeouts

If you regularly run into random timeouts, please re-read the top of this file and set the `COUCH_HOST` env var when running tests or the dev server, eg.:

```sh
```bash
$ CLIENT=firefox COUCH_HOST=http://admin:admin@127.0.0.1:5984 npm test
```

130 changes: 31 additions & 99 deletions bin/build-site.js
Original file line number Diff line number Diff line change
@@ -1,135 +1,67 @@
#!/usr/bin/env node

'use strict';

const { promisify } = require('node:util');
const exec = promisify(require('node:child_process').exec);
/*
ideally, we would eventually deprecate this entire file and rely exclusively
on 11ty for building and dev serving (https://www.11ty.dev/docs/watch-serve/).

var fs = require('fs');
const Path = require('node:path');
However, since all the styles are in LESS, and 11ty doesn’t build that, and
the LESS plugin for 11ty doesn’t seem to work with our setup, we’ll need to keep
build-site.js around for a little longer.
*/

var replace = require('replace');
var cssmin = require('cssmin');
const terser = require('terser');
'use strict';

const POUCHDB_CSS = resolvePath('docs/static/css/pouchdb.css');
const POUCHDB_LESS = resolvePath('docs/src/less/pouchdb/pouchdb.less');
import { execa } from 'execa';
import fs from 'fs';
import http_server from 'http-server';
import globWatcher from 'glob-watcher';

process.chdir('docs');
process.chdir('./');

async function buildCSS() {
fs.mkdirSync(__dirname + '/../docs/static/css', { recursive:true });
const cmd = [ resolvePath('node_modules/less/bin/lessc'), POUCHDB_LESS ].join(' ');
const { stdout } = await exec(cmd);
const minifiedCss = cssmin(stdout);
fs.writeFileSync(POUCHDB_CSS, minifiedCss);
console.log('Updated:', POUCHDB_CSS);
await execa({stdio: 'inherit'})`npm run build:less`;
console.log('=> Rebuilt CSS');
}

async function buildEleventy() {
await exec('npx @11ty/eleventy');
await checkForUnprocessedCurlies();
// --incremental sadly doesn't work in this setup, but the build is so fast
// it doesn’t really matter. However, on a full rebuild, 11ty logs every
// single built file, hence --quiet
await execa({stdio: 'inherit'})`eleventy --quiet`;
console.log('=> Rebuilt eleventy');

highlightEs6();
console.log('=> Highlighted ES6');

const srcPath = resolvePath('docs/src/code.js');
const targetPath = resolvePath('docs/_site/static/js/code.min.js');
const src = fs.readFileSync(srcPath, { encoding:'utf8' });
const mangle = { toplevel: true };
const output = { ascii_only: true };
const { code, error } = terser.minify(src, { mangle, output });
if (error) {
if (process.env.BUILD) {
throw error;
} else {
console.log(
`Javascript minification failed on line ${error.line} col ${error.col}:`,
error.message,
);
}
} else {
fs.writeFileSync(targetPath, code);
console.log('Minified javascript.');
}
}

async function checkForUnprocessedCurlies() {
// If unprocessed curlies are ever desired, add a way to ignore them.
async function buildEverything() {
try {
const res = await exec(`grep -Ern --include=\\*.html '\\{\\{|\\}\\}' ./_site/`);

console.log();
console.log('!!! UNPROCESSED CURLIES FOUND IN OUTPUT HTML FILE(S):');
console.log(res.stdout.trim());
console.log('!!! CHECK TEMPLATES ARE BEING FULLY PROCESSED.');
console.log();

if (process.env.BUILD) {
process.exit(1);
}
} catch (err) {
if (err.code === 1) {
return; // no problems found
}
throw err;
await buildCSS();
await buildEleventy();
} catch (error) {
console.error(error);
process.exit(1);
}
}

function highlightEs6() {
const path = resolvePath('docs/_site');

// TODO: this is a fragile and hacky way to get
// 'async' and 'await' to highlight correctly
// in blog posts & documentation.
replace({
regex: '<span class="nx">(await|async|of)</span>',
replacement: '<span class="kd">$1</span>',
paths: [path],
recursive: true
});
}

function onError(err) {
console.error(err);
process.exit(1);
}

function buildEverything() {
return Promise.resolve()
.then(buildCSS)
.then(buildEleventy)
.catch(onError);
}

function resolvePath(projectLocalPath) {
return Path.resolve(__dirname, '..', projectLocalPath);
}

if (!process.env.BUILD) {
const http_server = require('http-server');
const globWatcher = require('glob-watcher');
const watchGlob = (path, fn) => globWatcher(path, () => fn().catch(console.log));

// Simpler ways of blacklisting certain paths here would be very welcome.
fs.readdirSync('.')
fs.readdirSync('./docs')
.forEach(path => {
if (path === '_site') {
return;
}

if (fs.statSync(path).isDirectory()) {
watchGlob(`${path}/**`, buildEleventy);
if (fs.statSync(`./docs/${path}`).isDirectory()) {
watchGlob(`./docs/${path}/**`, buildEleventy);
} else {
watchGlob(path, buildEleventy);
watchGlob(`./docs/${path}`, buildEleventy);
}
});


watchGlob('src/less/**', buildCSS);
watchGlob('./docs/src/less/**', buildCSS);

http_server.createServer({root: '_site', cache: '-1'}).listen(4000);
http_server.createServer({root: './docs/_site', cache: '-1'}).listen(4000);
console.log('Server address: http://localhost:4000');
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
layout: default
layout: default.html
---

<article class="band">
Expand Down
2 changes: 1 addition & 1 deletion docs/_includes/anchor.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
{% else %}
{% assign class = 'h2' %}
{% endif %}
<div class='{{ class }}'><div class='anchor-id' id='{{ include.hash }}'></div><a class='anchor' href='#{{ include.hash }}' name='{{ include.hash }}'>{{ include.title }}</a>{% if include.edit %}<a data-toggle="tooltip" data-placement="top" title="Edit this on Github" class="icon-edit" href="{{ site.github.repository_url }}/edit/master/docs/_includes/api/{{ include.hash }}.html" target="_blank"></a>{% endif %}</div>
<div class='{{ class }}'><div class='anchor-id' id='{{ include.hash }}'></div><a class='anchor' href='#{{ include.hash }}' name='{{ include.hash }}'>{{ include.title | inlinemarkdown }}</a>{% if include.edit %}<a data-toggle="tooltip" data-placement="top" title="Edit this on Github" class="icon-edit" href="{{ site.github.repository_url }}/edit/master/docs/_includes/api/{{ include.hash }}.html" target="_blank"></a>{% endif %}</div>
8 changes: 4 additions & 4 deletions docs/_includes/api/active_tasks.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
{% include anchor.html edit="true" title="List active tasks" hash="active_tasks" %}

{% highlight "js" %}
{% highlight js %}
PouchDB.activeTasks.list()
{% endhighlight %}

List all active database tasks. There are three types of internal tasks: `database_compaction`, `view_indexing`, and `replication`. PouchDB will report progress of these tasks to the active tasks API and remove tasks as soon as they are completed or have failed.

#### Example Usage:

{% highlight "js" %}
{% highlight js %}
const tasks = PouchDB.activeTasks.list()
{% endhighlight %}

#### Example Result:

{% highlight "js" %}
{% highlight js %}
[{
"id": "d81fea92-8ce4-42df-bb2b-89a4e67536c3",
"name": "database_compaction",
Expand All @@ -29,7 +29,7 @@

You can use [JavaScript Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) to monitor calls to the active tasks API. For the `PouchDB.activeTasks.add()` function, which is used internally to announce new tasks to PouchDB, you can monitor calls as follows:

{% highlight "js" %}
{% highlight js %}
PouchDB.activeTasks.add = new Proxy(PouchDB.activeTasks.add, {
apply: (target, thisArg, argumentsList) => {
const task = argumentsList[0];
Expand Down
30 changes: 15 additions & 15 deletions docs/_includes/api/batch_create.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% include anchor.html edit="true" title="Create/update a batch of documents" hash="batch_create" %}

{% highlight "js" %}
{% highlight js %}
db.bulkDocs(docs, [options], [callback])
{% endhighlight %}

Expand All @@ -13,7 +13,7 @@
Put some new docs, providing the `_id`s:

{% include code/start.html id="bulk_docs_1" type="callback" %}
{% highlight "js" %}
{% highlight js %}
db.bulkDocs([
{title : 'Lisa Says', _id: 'doc1'},
{title : 'Space Oddity', _id: 'doc2'}
Expand All @@ -25,7 +25,7 @@
{% include code/end.html %}

{% include code/start.html id="bulk_docs_1" type="async" %}
{% highlight "js" %}
{% highlight js %}
try {
const result = await db.bulkDocs([
{title : 'Lisa Says', _id: 'doc1'},
Expand All @@ -38,7 +38,7 @@
{% include code/end.html %}

{% include code/start.html id="bulk_docs_1" type="promise" %}
{% highlight "js" %}
{% highlight js %}
db.bulkDocs([
{title : 'Lisa Says', _id: 'doc1'},
{title : 'Space Oddity', _id: 'doc2'}
Expand All @@ -53,7 +53,7 @@
Post some new docs and auto-generate the `_id`s:

{% include code/start.html id="bulk_docs_2" type="callback" %}
{% highlight "js" %}
{% highlight js %}
db.bulkDocs([
{title : 'Lisa Says'},
{title : 'Space Oddity'}
Expand All @@ -65,7 +65,7 @@
{% include code/end.html %}

{% include code/start.html id="bulk_docs_2" type="async" %}
{% highlight "js" %}
{% highlight js %}
try {
const result = await db.bulkDocs([
{title : 'Lisa Says'},
Expand All @@ -78,7 +78,7 @@
{% include code/end.html %}

{% include code/start.html id="bulk_docs_2" type="promise" %}
{% highlight "js" %}
{% highlight js %}
db.bulkDocs([
{title : 'Lisa Says'},
{title : 'Space Oddity'}
Expand All @@ -91,7 +91,7 @@
{% include code/end.html %}

#### Example Response:
{% highlight "js" %}
{% highlight js %}
[
{
"ok": true,
Expand All @@ -110,7 +110,7 @@
from the [put()/post() API](#create_document). If there are any errors, they
will be provided individually like so:

{% highlight "js" %}
{% highlight js %}
[
{ status: 409,
name: 'conflict',
Expand All @@ -131,7 +131,7 @@
You can also use `bulkDocs()` to update/delete many documents at once:

{% include code/start.html id="bulk_docs3" type="callback" %}
{% highlight "js" %}
{% highlight js %}
db.bulkDocs([
{
title : 'Lisa Says',
Expand All @@ -153,7 +153,7 @@
{% include code/end.html %}

{% include code/start.html id="bulk_docs3" type="async" %}
{% highlight "js" %}
{% highlight js %}
try {
const result = await db.bulkDocs([
{
Expand All @@ -176,7 +176,7 @@
{% include code/end.html %}

{% include code/start.html id="bulk_docs3" type="promise" %}
{% highlight "js" %}
{% highlight js %}
db.bulkDocs([
{
title : 'Lisa Says',
Expand All @@ -201,7 +201,7 @@
Or delete them:

{% include code/start.html id="bulk_docs_4" type="callback" %}
{% highlight "js" %}
{% highlight js %}
db.bulkDocs([
{
title : 'Lisa Says',
Expand All @@ -223,7 +223,7 @@
{% include code/end.html %}

{% include code/start.html id="bulk_docs_4" type="async" %}
{% highlight "js" %}
{% highlight js %}
try {
const result = await db.bulkDocs([
{
Expand All @@ -246,7 +246,7 @@
{% include code/end.html %}

{% include code/start.html id="bulk_docs_4" type="promise" %}
{% highlight "js" %}
{% highlight js %}
db.bulkDocs([
{
title : 'Lisa Says',
Expand Down
Loading