@automerge/create-repo-node-app 2.6.0-subduction.8 → 2.7.0-authors.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.
- package/README.md +7 -9
- package/dist/index.js +73 -42
- package/package.json +22 -4
- package/template/.oxlintrc.json +8 -0
- package/template/README.md +28 -0
- package/template/index.ts +20 -0
- package/template/package.json +24 -0
- package/template/tsconfig.json +12 -0
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/postbuild.js +0 -3
- package/src/index.ts +0 -57
- package/tsconfig.json +0 -17
- package/vitest.config.ts +0 -11
package/README.md
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
# Scaffolding for a node `automerge-repo` app
|
|
2
2
|
|
|
3
|
-
This generates a simple
|
|
3
|
+
This generates a simple TypeScript project with the dependencies for a repo that
|
|
4
|
+
synchronises over WebSockets and stores data on the filesystem.
|
|
4
5
|
|
|
5
6
|
## How to use
|
|
6
7
|
|
|
7
|
-
### NPM
|
|
8
|
-
|
|
9
8
|
```
|
|
10
9
|
npm create @automerge/repo-node-app <your project name>
|
|
11
10
|
```
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
yarn create @automerge/repo-node-app <your project name>
|
|
17
|
-
```
|
|
12
|
+
(or `pnpm create`, `yarn create`, `bun create` — the scaffold detects your
|
|
13
|
+
package manager.)
|
|
18
14
|
|
|
19
|
-
|
|
15
|
+
The project runs with Node's built-in TypeScript support, so there is no build
|
|
16
|
+
step. Change into the directory, install dependencies, and start editing
|
|
17
|
+
`index.ts`.
|
package/dist/index.js
CHANGED
|
@@ -1,47 +1,78 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const repo = new Repo({
|
|
30
|
-
storage: new NodeFSStorageAdapter("./db"),
|
|
31
|
-
network: [new WebSocketClientAdapter("wss://sync.automerge.org")]
|
|
32
|
-
})
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { intro, outro, text, isCancel, cancel, log } from "@clack/prompts";
|
|
6
|
+
const detectPackageManager = () => {
|
|
7
|
+
const ua = process.env.npm_config_user_agent ?? "";
|
|
8
|
+
return ua.split(" ")[0]?.split("/")[0] || "npm";
|
|
9
|
+
};
|
|
10
|
+
const copy = (src, dest) => {
|
|
11
|
+
if (fs.statSync(src).isDirectory()) {
|
|
12
|
+
copyDir(src, dest);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
fs.copyFileSync(src, dest);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const copyDir = (srcDir, destDir) => {
|
|
19
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
20
|
+
for (const file of fs.readdirSync(srcDir)) {
|
|
21
|
+
copy(path.resolve(srcDir, file), path.resolve(destDir, file));
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
// Written here rather than shipped as a template file: npm strips files named
|
|
25
|
+
// .gitignore from published packages, so the template can't carry one directly.
|
|
26
|
+
const GITIGNORE = `node_modules
|
|
27
|
+
automerge-data
|
|
28
|
+
*.log
|
|
33
29
|
`;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const projectName = process.argv[2];
|
|
30
|
+
const main = async () => {
|
|
31
|
+
intro("create-repo-node-app · Automerge for Node");
|
|
32
|
+
let projectName = process.argv[2];
|
|
38
33
|
if (!projectName) {
|
|
39
|
-
|
|
34
|
+
const answer = await text({
|
|
35
|
+
message: "Project name?",
|
|
36
|
+
placeholder: "my-automerge-app",
|
|
37
|
+
validate: value => value && value.trim().length > 0
|
|
38
|
+
? undefined
|
|
39
|
+
: "Please enter a project name",
|
|
40
|
+
});
|
|
41
|
+
if (isCancel(answer)) {
|
|
42
|
+
cancel("Scaffolding cancelled.");
|
|
43
|
+
process.exit(0);
|
|
44
|
+
}
|
|
45
|
+
projectName = answer.trim();
|
|
46
|
+
}
|
|
47
|
+
const root = path.join(process.cwd(), projectName);
|
|
48
|
+
if (fs.existsSync(root)) {
|
|
49
|
+
cancel(`Directory "${projectName}" already exists.`);
|
|
40
50
|
process.exit(1);
|
|
41
51
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
const templateDir = path.resolve(fileURLToPath(import.meta.url), "../../template");
|
|
53
|
+
fs.mkdirSync(root, { recursive: true });
|
|
54
|
+
for (const file of fs.readdirSync(templateDir)) {
|
|
55
|
+
if (file === "package.json")
|
|
56
|
+
continue;
|
|
57
|
+
copy(path.join(templateDir, file), path.join(root, file));
|
|
58
|
+
}
|
|
59
|
+
// Copy package.json with the chosen project name.
|
|
60
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(templateDir, "package.json"), "utf-8"));
|
|
61
|
+
pkg.name = projectName;
|
|
62
|
+
fs.writeFileSync(path.join(root, "package.json"), JSON.stringify(pkg, null, 2) + "\n");
|
|
63
|
+
fs.writeFileSync(path.join(root, ".gitignore"), GITIGNORE);
|
|
64
|
+
log.success(`Created ${projectName}`);
|
|
65
|
+
const pm = detectPackageManager();
|
|
66
|
+
const run = pm === "npm" ? "npm run" : pm;
|
|
67
|
+
outro([
|
|
68
|
+
"Next steps:",
|
|
69
|
+
` cd ${projectName}`,
|
|
70
|
+
` ${pm} install`,
|
|
71
|
+
` ${run} start`,
|
|
72
|
+
].join("\n"));
|
|
73
|
+
};
|
|
74
|
+
main().catch(error => {
|
|
75
|
+
console.error(error);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,18 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automerge/create-repo-node-app",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0-authors.0",
|
|
4
4
|
"description": "Create an automerge-repo app for node",
|
|
5
|
-
"repository": "https://github.com/automerge/automerge-repo/tree/
|
|
5
|
+
"repository": "https://github.com/automerge/automerge-repo/tree/main/packages/create-repo-node-app",
|
|
6
6
|
"author": "Alex Good <alex@memoryandthought.me>",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"type": "module",
|
|
9
|
-
"
|
|
9
|
+
"files": [
|
|
10
|
+
"dist/index.js",
|
|
11
|
+
"template"
|
|
12
|
+
],
|
|
10
13
|
"publishConfig": {
|
|
11
14
|
"access": "public",
|
|
12
15
|
"tag": "subduction"
|
|
13
16
|
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@clack/prompts": "^1.4.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^22.19.19",
|
|
22
|
+
"execa": "^9.6.1",
|
|
23
|
+
"typescript": "^6.0.3"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=22.13"
|
|
27
|
+
},
|
|
14
28
|
"scripts": {
|
|
15
29
|
"build": "tsc",
|
|
16
|
-
"postbuild": "node postbuild.js"
|
|
30
|
+
"postbuild": "node postbuild.js",
|
|
31
|
+
"test": "node test.js"
|
|
32
|
+
},
|
|
33
|
+
"bin": {
|
|
34
|
+
"create-repo-node-app": "dist/index.js"
|
|
17
35
|
}
|
|
18
36
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Automerge node app
|
|
2
|
+
|
|
3
|
+
A starter [Automerge](https://automerge.org) app for Node. It keeps a repo of
|
|
4
|
+
documents on the local filesystem and syncs them with a WebSocket sync server.
|
|
5
|
+
|
|
6
|
+
## Run
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
pnpm install
|
|
10
|
+
pnpm start
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`pnpm start` runs `index.ts` directly using Node's built-in TypeScript support
|
|
14
|
+
(Node 22.18+), so there is no build step. Edit `index.ts` to build your app.
|
|
15
|
+
|
|
16
|
+
## Type-check
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
pnpm typecheck
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Lint
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
pnpm lint
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Linting uses [oxlint](https://oxc.rs).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Repo } from "@automerge/automerge-repo"
|
|
2
|
+
import { WebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket"
|
|
3
|
+
import { NodeFSStorageAdapter } from "@automerge/automerge-repo-storage-nodefs"
|
|
4
|
+
|
|
5
|
+
// A repo that persists documents to the local filesystem and syncs them with a
|
|
6
|
+
// WebSocket sync server. Point the adapter at your own server for production.
|
|
7
|
+
const repo = new Repo({
|
|
8
|
+
storage: new NodeFSStorageAdapter("./automerge-data"),
|
|
9
|
+
network: [new WebSocketClientAdapter("wss://sync.automerge.org")],
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
// Create a document and make a change. Share `handle.url` with another peer
|
|
13
|
+
// (or load it elsewhere) to sync the same document.
|
|
14
|
+
const handle = repo.create<{ count: number }>({ count: 0 })
|
|
15
|
+
handle.change(doc => {
|
|
16
|
+
doc.count += 1
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
console.log(`Created document: ${handle.url}`)
|
|
20
|
+
console.log("Syncing… press Ctrl+C to stop.")
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "projectName",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=22.18"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node index.ts",
|
|
11
|
+
"typecheck": "tsc",
|
|
12
|
+
"lint": "oxlint"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@automerge/automerge-repo": "^2.5.6",
|
|
16
|
+
"@automerge/automerge-repo-network-websocket": "^2.5.6",
|
|
17
|
+
"@automerge/automerge-repo-storage-nodefs": "^2.5.6"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/node": "^22.19.0",
|
|
21
|
+
"oxlint": "^1.67.0",
|
|
22
|
+
"typescript": "^6.0.3"
|
|
23
|
+
}
|
|
24
|
+
}
|
package/dist/index.d.ts
DELETED
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/postbuild.js
DELETED
package/src/index.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import fs from "fs"
|
|
4
|
-
import path from "path"
|
|
5
|
-
import child_process from "child_process"
|
|
6
|
-
|
|
7
|
-
const execSync = child_process.execSync
|
|
8
|
-
|
|
9
|
-
function createPackageJson(projectName: string) {
|
|
10
|
-
const packageJson = {
|
|
11
|
-
name: projectName,
|
|
12
|
-
version: "1.0.0",
|
|
13
|
-
description: "",
|
|
14
|
-
main: "index.js",
|
|
15
|
-
type: "module",
|
|
16
|
-
scripts: {
|
|
17
|
-
start: "node index.js",
|
|
18
|
-
},
|
|
19
|
-
dependencies: {
|
|
20
|
-
"@automerge/automerge-repo": "^1.0",
|
|
21
|
-
"@automerge/automerge-repo-network-websocket": "^1.0",
|
|
22
|
-
"@automerge/automerge-repo-storage-nodefs": "^1.0",
|
|
23
|
-
},
|
|
24
|
-
}
|
|
25
|
-
fs.writeFileSync(
|
|
26
|
-
path.join(projectName, "package.json"),
|
|
27
|
-
JSON.stringify(packageJson, null, 2) + "\n"
|
|
28
|
-
)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function createIndexJs(projectName: string) {
|
|
32
|
-
const indexJsContent = `import { Repo } from "@automerge/automerge-repo"
|
|
33
|
-
import { WebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket"
|
|
34
|
-
import { NodeFSStorageAdapter } from "@automerge/automerge-repo-storage-nodefs"
|
|
35
|
-
|
|
36
|
-
const repo = new Repo({
|
|
37
|
-
storage: new NodeFSStorageAdapter("./db"),
|
|
38
|
-
network: [new WebSocketClientAdapter("wss://sync.automerge.org")]
|
|
39
|
-
})
|
|
40
|
-
`
|
|
41
|
-
fs.writeFileSync(path.join(projectName, "index.js"), indexJsContent)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function main() {
|
|
45
|
-
const projectName = process.argv[2]
|
|
46
|
-
if (!projectName) {
|
|
47
|
-
console.error("Please provide a project name")
|
|
48
|
-
process.exit(1)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
fs.mkdirSync(projectName)
|
|
52
|
-
createPackageJson(projectName)
|
|
53
|
-
createIndexJs(projectName)
|
|
54
|
-
execSync(`cd ${projectName} && npm install`, { stdio: "inherit" })
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
main()
|
package/tsconfig.json
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ESNext",
|
|
4
|
-
"jsx": "react",
|
|
5
|
-
"module": "NodeNext",
|
|
6
|
-
"moduleResolution": "Node16",
|
|
7
|
-
"declaration": true,
|
|
8
|
-
"declarationMap": true,
|
|
9
|
-
"outDir": "./dist",
|
|
10
|
-
"esModuleInterop": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"strict": true,
|
|
13
|
-
"skipLibCheck": true
|
|
14
|
-
},
|
|
15
|
-
"include": ["src/**/*.ts"],
|
|
16
|
-
"exclude": ["dist"]
|
|
17
|
-
}
|