mirror of
https://github.com/morten-olsen/plainidx.git
synced 2026-02-08 01:06:24 +01:00
prepare for client/server split
This commit is contained in:
@@ -6,6 +6,17 @@
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/exports.js"
|
||||
},
|
||||
"./manifest": {
|
||||
"import": "./dist/manifest.js"
|
||||
},
|
||||
"./plugin": {
|
||||
"import": "./dist/plugin.js"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc --build"
|
||||
},
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
import { createActionApiRoute, type Database, Plugin, z } from '@plainidx/plainidx';
|
||||
import { migrations } from './migrations/migrations.js';
|
||||
|
||||
class CorePlugin extends Plugin {
|
||||
#db?: Promise<Database>;
|
||||
|
||||
public readonly name = '@builtin/core';
|
||||
|
||||
public actions = {
|
||||
setTags: createActionApiRoute({
|
||||
input: z.object({
|
||||
document: z.string(),
|
||||
tags: z.array(z.string()),
|
||||
}),
|
||||
output: z.undefined(),
|
||||
handle: async ({ document, tags }) => {
|
||||
await this.setTags(document, tags);
|
||||
return undefined;
|
||||
},
|
||||
}),
|
||||
getTags: createActionApiRoute({
|
||||
output: z.array(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
count: z.number(),
|
||||
}),
|
||||
),
|
||||
handle: async () => {
|
||||
return this.getTags();
|
||||
},
|
||||
}),
|
||||
setTitle: createActionApiRoute({
|
||||
input: z.object({
|
||||
document: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
output: z.undefined(),
|
||||
handle: async ({ document, title }) => {
|
||||
await this.setTitle(document, title);
|
||||
return undefined;
|
||||
},
|
||||
}),
|
||||
getTitles: createActionApiRoute({
|
||||
output: z.array(
|
||||
z.object({
|
||||
document: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
),
|
||||
handle: async () => {
|
||||
return this.getTitles();
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
#getDatabase = async () => {
|
||||
if (!this.#db) {
|
||||
this.#db = this.getDB('data', migrations);
|
||||
}
|
||||
return this.#db;
|
||||
};
|
||||
|
||||
public getTags = async () => {
|
||||
const db = await this.#getDatabase();
|
||||
return db('tags')
|
||||
.select([db.raw('tag as name'), db.raw('count(document) as count')])
|
||||
.groupBy('tag');
|
||||
};
|
||||
|
||||
public setTags = async (document: string, tags: string[]) => {
|
||||
const db = await this.#getDatabase();
|
||||
await db('tags').where({ document }).delete();
|
||||
if (tags.length) {
|
||||
await db('tags').insert(tags.map((tag) => ({ tag, document })));
|
||||
}
|
||||
};
|
||||
|
||||
public setTitle = async (document: string, title: string) => {
|
||||
const db = await this.#getDatabase();
|
||||
await db('titles').where({ document }).insert({ document, title }).onConflict('document').merge();
|
||||
};
|
||||
|
||||
public getTitles = async () => {
|
||||
const db = await this.#getDatabase();
|
||||
return await db('titles').select('*');
|
||||
};
|
||||
}
|
||||
|
||||
export { CorePlugin };
|
||||
@@ -1 +1,2 @@
|
||||
export { CorePlugin } from './core.js';
|
||||
export { core } from './plugin.js';
|
||||
export { CorePlugin } from './manifest.js';
|
||||
|
||||
31
packages/plugin-core/src/manifest.ts
Normal file
31
packages/plugin-core/src/manifest.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { Manifest, z } from '@plainidx/plainidx';
|
||||
|
||||
const CorePlugin = {
|
||||
id: 'buildin-core',
|
||||
name: 'Core Plugin',
|
||||
version: '0.0.1',
|
||||
config: z.any(),
|
||||
backend: {
|
||||
main: './dist/plugin.js',
|
||||
actions: {
|
||||
getTitles: {
|
||||
input: z.object({}),
|
||||
output: z.array(z.object({ location: z.string(), title: z.string() })),
|
||||
},
|
||||
getTags: {
|
||||
input: z.object({}),
|
||||
output: z.array(z.string()),
|
||||
},
|
||||
setData: {
|
||||
input: z.object({
|
||||
location: z.string(),
|
||||
title: z.string(),
|
||||
tags: z.array(z.string()),
|
||||
}),
|
||||
output: z.any(),
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies Manifest;
|
||||
|
||||
export { CorePlugin };
|
||||
@@ -5,15 +5,15 @@ const migrations: DatabaseMigration[] = [
|
||||
name: 'init',
|
||||
up: async (db) => {
|
||||
await db.schema.createTable('tags', (table) => {
|
||||
table.string('tag').notNullable();
|
||||
table.string('document').notNullable();
|
||||
table.primary(['tag', 'document']);
|
||||
table.index('document');
|
||||
table.index('tag');
|
||||
table.string('name').notNullable();
|
||||
table.string('location').notNullable();
|
||||
table.primary(['name', 'location']);
|
||||
table.index('location');
|
||||
table.index('name');
|
||||
});
|
||||
|
||||
await db.schema.createTable('titles', (table) => {
|
||||
table.string('document').primary().notNullable();
|
||||
table.string('location').primary().notNullable();
|
||||
table.string('title').notNullable();
|
||||
});
|
||||
},
|
||||
|
||||
39
packages/plugin-core/src/plugin.ts
Normal file
39
packages/plugin-core/src/plugin.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { createPlugin } from '@plainidx/plainidx';
|
||||
import { CorePlugin } from './manifest.js';
|
||||
import { migrations } from './migrations/migrations.js';
|
||||
|
||||
const core = createPlugin(CorePlugin, ({ getDb }) => {
|
||||
const dbPromise = getDb('data', migrations);
|
||||
return {
|
||||
backend: true,
|
||||
actions: {
|
||||
getTitles: async () => {
|
||||
const db = await dbPromise;
|
||||
const results = await db('titles').select(['location', 'title']);
|
||||
return results;
|
||||
},
|
||||
getTags: async () => {
|
||||
const db = await dbPromise;
|
||||
const results = await db('tags')
|
||||
.select(['name', db.raw('count(*) as count')])
|
||||
.groupBy('name');
|
||||
return results;
|
||||
},
|
||||
setData: async ({ location, title, tags }) => {
|
||||
const db = await dbPromise;
|
||||
const currentTitle = await db('titles').select('title').where({ location }).first();
|
||||
await db.transaction(async (trx) => {
|
||||
await trx('tags').delete().where({ location });
|
||||
await trx('tags').insert(tags.map((tag) => ({ name: tag, location })));
|
||||
if (currentTitle) {
|
||||
await trx('titles').update({ title }).where({ location });
|
||||
} else {
|
||||
await trx('titles').insert({ location, title });
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export { core };
|
||||
Reference in New Issue
Block a user