Skip to content

Commit 42191bc

Browse files
committed
enhance(schema); relatime schema updates for server
1 parent 03ed320 commit 42191bc

File tree

11 files changed

+161
-57
lines changed

11 files changed

+161
-57
lines changed

packages/api-server/src/modules/schemas/index.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import {
44
SchemaDeleteRequest,
55
SchemaQueryPayload,
66
SchemaQueryRequest,
7+
SchemaUpdatePayload,
8+
SchemaUpdateRequest,
79
SchemaWritePayload,
810
SchemaWriteRequest,
911
} from "@dendronhq/common-server";
@@ -66,4 +68,23 @@ export class SchemaController {
6668
}
6769
return await engine.querySchema(qs);
6870
}
71+
72+
async update({
73+
ws,
74+
schema,
75+
}: SchemaUpdateRequest): Promise<SchemaUpdatePayload> {
76+
const engine = await MemoryStore.instance().get<DEngineV2>(`ws:${ws}`);
77+
if (!engine) {
78+
throw "No Engine";
79+
}
80+
try {
81+
await engine.updateSchema(schema);
82+
return { error: null };
83+
} catch (err) {
84+
return {
85+
error: new DendronError({ msg: JSON.stringify(err) }),
86+
data: undefined,
87+
};
88+
}
89+
}
6990
}

packages/api-server/src/routes/schema.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
SchemaDeleteRequest,
33
SchemaQueryRequest,
4+
SchemaUpdateRequest,
45
SchemaWriteRequest,
56
} from "@dendronhq/common-server";
67
import { Request, Response, Router } from "express";
@@ -22,6 +23,13 @@ router.post("/query", async (req: Request, res: Response) => {
2223
res.json(resp);
2324
});
2425

26+
router.post("/update", async (req: Request, res: Response) => {
27+
const resp = await SchemaController.instance().update(
28+
req.body as SchemaUpdateRequest
29+
);
30+
res.json(resp);
31+
});
32+
2533
router.post("/write", async (req: Request, res: Response) => {
2634
const resp = await SchemaController.instance().create(
2735
req.body as SchemaWriteRequest

packages/common-server/src/filesv2.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
DNodeUtilsV2,
3+
DVault,
34
NotePropsV2,
45
NoteUtilsV2,
56
SchemaModuleOptsV2,
@@ -24,6 +25,20 @@ export function file2Schema(fpath: string): SchemaModulePropsV2 {
2425
) as SchemaModuleOptsV2;
2526
return SchemaParserV2.parseRaw(schemaOpts, { root, fname });
2627
}
28+
export function string2Schema({
29+
vault,
30+
content,
31+
fname,
32+
}: {
33+
vault: DVault;
34+
content: string;
35+
fname: string;
36+
}) {
37+
const schemaOpts = YAML.safeLoad(content, {
38+
schema: YAML.JSON_SCHEMA,
39+
}) as SchemaModuleOptsV2;
40+
return SchemaParserV2.parseRaw(schemaOpts, { root: vault.fsPath, fname });
41+
}
2742

2843
export function string2Note({
2944
content,

packages/dendron-cli/src/commands/__tests__/importPod.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
NodeTestUtils,
44
writeYAML,
55
} from "@dendronhq/common-server";
6-
import { FileImportPod, getPodConfigPath } from "@dendronhq/pods-core";
6+
import { getPodConfigPath, MarkdownImportPod } from "@dendronhq/pods-core";
77
import fs, { ensureDirSync } from "fs-extra";
88
import path from "path";
99
import { ImportPodCLICommand } from "../importPod";
@@ -36,7 +36,7 @@ describe("import file pod", async () => {
3636
test("file import, no config", async () => {
3737
try {
3838
await ImportPodCLICommand.run({
39-
podId: FileImportPod.id,
39+
podId: MarkdownImportPod.id,
4040
wsRoot,
4141
vault,
4242
});
@@ -48,13 +48,13 @@ describe("import file pod", async () => {
4848
test("config present, default", async () => {
4949
const configPath = getPodConfigPath(
5050
path.join(wsRoot, "pods"),
51-
FileImportPod
51+
MarkdownImportPod
5252
);
5353
ensureDirSync(path.dirname(configPath));
5454
writeYAML(configPath, { src: importSrc });
5555

5656
const cmd = await ImportPodCLICommand.run({
57-
podId: FileImportPod.id,
57+
podId: MarkdownImportPod.id,
5858
wsRoot,
5959
vault,
6060
});

packages/engine-server/src/__tests__/__snapshots__/enginev2.spec.ts.snap

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -557,34 +557,6 @@ Object {
557557
}
558558
`;
559559

560-
exports[`engine, schema/ write/ update schema, add new prop to module: new schema file 1`] = `
561-
Object {
562-
"imports": Array [],
563-
"schemas": Array [
564-
Object {
565-
"children": Array [
566-
"ch1",
567-
"ch2",
568-
],
569-
"id": "foo",
570-
"parent": "root",
571-
"title": "foo",
572-
},
573-
Object {
574-
"children": Array [],
575-
"id": "ch1",
576-
"title": "ch1",
577-
},
578-
Object {
579-
"children": Array [],
580-
"id": "ch2",
581-
"title": "ch2",
582-
},
583-
],
584-
"version": 1,
585-
}
586-
`;
587-
588560
exports[`note and schema basics/ root and two notes 1`] = `
589561
Object {
590562
"foo": Object {

packages/engine-server/src/__tests__/enginev2.spec.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,6 @@ describe("engine, schema/", () => {
142142
// query should have same results
143143
const resp = await engine.querySchema("*");
144144
expect(resp.data.length).toEqual(2);
145-
146-
// should be written to file
147-
const data = readYAML(path.join(vaultDir, "foo.schema.yml"));
148-
expect(data).toMatchSnapshot("new schema file");
149-
expect(data.schemas.length).toEqual(3);
150-
// should have added new child
151-
expect(_.find(data.schemas, { id: "foo" }).children.length).toEqual(2);
152145
});
153146

154147
test("write new module", async () => {

packages/engine-server/src/drivers/file/storev2.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,9 @@ export class FileStorageV2 implements DStoreV2 {
440440

441441
async updateSchema(schemaModule: SchemaModulePropsV2) {
442442
this.schemas[schemaModule.root.id] = schemaModule;
443-
const vaultDir = this.vaults[0];
444-
await schemaModuleProps2File(schemaModule, vaultDir, schemaModule.fname);
443+
// const vaultDir = this.vaults[0];
444+
// await schemaModuleProps2File(schemaModule, vaultDir, schemaModule.fname);
445+
// TODO: update notes
445446
}
446447

447448
async writeNote(
@@ -478,6 +479,8 @@ export class FileStorageV2 implements DStoreV2 {
478479
}
479480

480481
async writeSchema(schemaModule: SchemaModulePropsV2) {
481-
return this.updateSchema(schemaModule);
482+
this.schemas[schemaModule.root.id] = schemaModule;
483+
const vaultDir = this.vaults[0];
484+
await schemaModuleProps2File(schemaModule, vaultDir, schemaModule.fname);
482485
}
483486
}

packages/engine-server/src/engineClient.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,10 @@ export class DendronEngineClient implements DEngineClientV2 {
265265
return _.defaults(out, { data: [] });
266266
}
267267

268-
async updateSchema(_schema: SchemaModulePropsV2): Promise<void> {
269-
throw Error("not implemented");
268+
async updateSchema(schema: SchemaModulePropsV2): Promise<void> {
269+
await this.api.schemaUpdate({ schema, ws: this.ws });
270+
await this.refreshSchemas([schema]);
271+
return;
270272
}
271273

272274
async writeSchema(schema: SchemaModulePropsV2): Promise<void> {

packages/plugin-core/src/utils.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
1+
import {
2+
DendronError,
3+
DEngine,
4+
DEngineClientV2,
5+
DNodeUtils,
6+
DNodeUtilsV2,
7+
DVault,
8+
NoteUtilsV2,
9+
SchemaUtils,
10+
} from "@dendronhq/common-all";
111
import { FileTestUtils, resolveTilde } from "@dendronhq/common-server";
212
import fs from "fs-extra";
313
import _ from "lodash";
14+
import _md from "markdown-it";
15+
import moment from "moment";
416
import os from "os";
517
import path from "path";
618
import * as vscode from "vscode";
@@ -11,19 +23,8 @@ import {
1123
_noteAddBehaviorEnum,
1224
} from "./constants";
1325
import { FileItem } from "./external/fileutils/FileItem";
14-
import _md from "markdown-it";
15-
import { DendronWorkspace } from "./workspace";
16-
import {
17-
DendronError,
18-
DEngine,
19-
DEngineClientV2,
20-
DNodeUtils,
21-
DNodeUtilsV2,
22-
NoteUtilsV2,
23-
SchemaUtils,
24-
} from "@dendronhq/common-all";
25-
import moment from "moment";
2626
import { EngineAPIService } from "./services/EngineAPIService";
27+
import { DendronWorkspace } from "./workspace";
2728

2829
export class DisposableStore {
2930
private _toDispose = new Set<vscode.Disposable>();
@@ -489,4 +490,15 @@ export class DendronClientUtilsV2 {
489490
}
490491
return smod;
491492
};
493+
494+
static getVault({
495+
dirname,
496+
}: {
497+
dirname: string;
498+
engine: DEngineClientV2;
499+
}): DVault {
500+
return {
501+
fsPath: dirname,
502+
};
503+
}
492504
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { DEngineClientV2 } from "@dendronhq/common-all";
2+
import { string2Schema } from "@dendronhq/common-server";
3+
import _ from "lodash";
4+
import path from "path";
5+
import * as vscode from "vscode";
6+
import { Logger } from "../logger";
7+
import { DendronClientUtilsV2 } from "../utils";
8+
import { DendronWorkspace } from "../workspace";
9+
10+
export class SchemaWatcher {
11+
public watcher: vscode.FileSystemWatcher;
12+
/**
13+
* Should watching be paused
14+
*/
15+
public pause: boolean;
16+
public L = Logger;
17+
public ws: DendronWorkspace;
18+
public engine: DEngineClientV2;
19+
20+
constructor({ vaults }: { vaults: vscode.WorkspaceFolder[] }) {
21+
const rootFolder = vaults[0];
22+
const pattern = new vscode.RelativePattern(rootFolder, "*.schema.yml");
23+
const watcher = vscode.workspace.createFileSystemWatcher(
24+
pattern,
25+
true,
26+
false,
27+
true
28+
);
29+
this.watcher = watcher;
30+
this.ws = DendronWorkspace.instance();
31+
this.engine = this.ws.getEngine();
32+
this.pause = false;
33+
}
34+
35+
activate(context: vscode.ExtensionContext) {
36+
context.subscriptions.push(
37+
this.watcher.onDidChange(this.onDidChange, this)
38+
);
39+
}
40+
41+
async onDidChange(uri: vscode.Uri) {
42+
const ctx = "SchemaWatcher:onDidChange";
43+
if (this.pause) {
44+
return;
45+
}
46+
this.L.info({ ctx, uri });
47+
const engine = DendronWorkspace.instance().getEngine();
48+
const fname = path.basename(uri.fsPath, ".schema.yml");
49+
const dirname = path.dirname(uri.fsPath);
50+
const vault = DendronClientUtilsV2.getVault({ dirname, engine });
51+
const document = await vscode.workspace.openTextDocument(uri);
52+
const content = document.getText();
53+
54+
try {
55+
const maybeSchema = string2Schema({ vault, content, fname });
56+
await engine.updateSchema(maybeSchema);
57+
vscode.window.showInformationMessage("schema updated");
58+
} catch (err) {
59+
if (err.msg) {
60+
vscode.window.showErrorMessage(err.msg);
61+
} else {
62+
vscode.window.showErrorMessage(err.message);
63+
}
64+
return;
65+
}
66+
}
67+
68+
static refreshTree = _.debounce(() => {
69+
const ctx = "refreshTree";
70+
Logger.info({ ctx });
71+
DendronWorkspace.instance().dendronTreeView?.treeProvider.refresh();
72+
}, 100);
73+
}

0 commit comments

Comments
 (0)