diff --git a/app/src/plugins/data/timestamp.plugin.spec.ts b/app/src/plugins/data/timestamp.plugin.spec.ts index bdf8811d..87778d98 100644 --- a/app/src/plugins/data/timestamp.plugin.spec.ts +++ b/app/src/plugins/data/timestamp.plugin.spec.ts @@ -71,4 +71,54 @@ describe("timestamps plugin", () => { expect(updatedData.updated_at).toBeDefined(); expect(updatedData.updated_at).toBeInstanceOf(Date); }); + + test("index strategy", async () => { + const app = createApp({ + config: { + data: em({ + posts: entity("posts", { + title: text(), + }), + }).toJSON(), + }, + options: { + plugins: [timestamps({ entities: ["posts"] })], + }, + }); + await app.build(); + expect(app.em.indices.length).toBe(0); + { + const app = createApp({ + config: { + data: em({ + posts: entity("posts", { + title: text(), + }), + }).toJSON(), + }, + options: { + plugins: [timestamps({ entities: ["posts"], indexStrategy: "composite" })], + }, + }); + await app.build(); + expect(app.em.indices.length).toBe(1); + } + + { + const app = createApp({ + config: { + data: em({ + posts: entity("posts", { + title: text(), + }), + }).toJSON(), + }, + options: { + plugins: [timestamps({ entities: ["posts"], indexStrategy: "individual" })], + }, + }); + await app.build(); + expect(app.em.indices.length).toBe(2); + } + }); }); diff --git a/app/src/plugins/data/timestamps.plugin.ts b/app/src/plugins/data/timestamps.plugin.ts index 0de5a94e..aa22e5a3 100644 --- a/app/src/plugins/data/timestamps.plugin.ts +++ b/app/src/plugins/data/timestamps.plugin.ts @@ -4,6 +4,7 @@ import { $console } from "bknd/utils"; export type TimestampsPluginOptions = { entities: string[]; setUpdatedOnCreate?: boolean; + indexStrategy?: "composite" | "individual"; }; /** @@ -19,6 +20,7 @@ export type TimestampsPluginOptions = { export function timestamps({ entities = [], setUpdatedOnCreate = true, + indexStrategy, }: TimestampsPluginOptions): AppPlugin { return (app: App) => ({ name: "timestamps", @@ -29,19 +31,35 @@ export function timestamps({ } const appEntities = app.em.entities.map((e) => e.name); + const actualEntities = entities.filter((e) => appEntities.includes(e)); return em( Object.fromEntries( - entities - .filter((e) => appEntities.includes(e)) - .map((e) => [ - e, - entity(e, { - created_at: datetime(), - updated_at: datetime(), - }), - ]), + actualEntities.map((e) => [ + e, + entity(e, { + created_at: datetime(), + updated_at: datetime(), + }), + ]), ), + (fns, schema) => { + if (indexStrategy) { + for (const entity of actualEntities) { + if (entity in schema) { + switch (indexStrategy) { + case "composite": + fns.index(schema[entity]!).on(["created_at", "updated_at"]); + break; + case "individual": + fns.index(schema[entity]!).on(["created_at"]); + fns.index(schema[entity]!).on(["updated_at"]); + break; + } + } + } + } + }, ); }, onBuilt: async () => {