@pepys/api 0.0.1 → 0.1.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 +3 -2
- package/package.json +13 -9
- package/src/app/create-app.ts +27 -4
- package/src/app/create-router.ts +65 -48
- package/src/app/run-plugin-query.ts +31 -0
- package/src/client/deployment-client.ts +9 -0
- package/src/config/read-api-config.ts +8 -1
- package/src/index.ts +5 -6
- package/src/queries/build-query-context.ts +13 -0
- package/src/queries/entity-kinds/build-entity-kind-index.ts +17 -0
- package/src/queries/get-entity/read-entity.ts +43 -27
- package/src/queries/neighbourhood/pick-link-types.ts +30 -0
- package/src/queries/neighbourhood/take-hop.ts +97 -0
- package/src/queries/neighbourhood/walk-neighbourhood.ts +121 -0
- package/src/queries/types.ts +12 -5
- package/src/serve/serve-api.ts +53 -0
- package/src/store-reader/build-shared-views-plugin.ts +86 -0
- package/src/store-reader/create-store-reader.ts +146 -82
- package/src/store-reader/pick-attached-files.ts +45 -0
- package/src/store-reader/read-change-operations.ts +18 -9
- package/src/store-reader/read-offsets.ts +16 -11
- package/src/utils/compare-text.ts +8 -0
- package/src/change-feed/change-feed.ts +0 -33
- package/src/principal/principal.ts +0 -10
- package/src/queries/get-entity/find-entity-consumer.ts +0 -23
- package/src/store-reader/open-consumer-database.ts +0 -6
- package/src/store-reader/read-pull-requests.ts +0 -13
- package/src/store-reader/store-reader.ts +0 -37
|
@@ -1,28 +1,33 @@
|
|
|
1
|
-
import type { Result } from '@pepys/kit';
|
|
2
|
-
import
|
|
1
|
+
import type { ConsumerDeclaration, Result, StoreReader, StoreReaderFailure } from '@pepys/kit';
|
|
2
|
+
import { sql } from 'kysely';
|
|
3
|
+
import { z } from 'zod';
|
|
3
4
|
|
|
4
5
|
interface Offset {
|
|
5
6
|
stream: string;
|
|
6
7
|
lastSeqNum: number;
|
|
7
8
|
}
|
|
8
9
|
|
|
10
|
+
const offsetRowSchema = z.object({ stream: z.string(), last_seq_num: z.number() });
|
|
11
|
+
const offsetRowsSchema = z.object({ rows: z.array(offsetRowSchema) });
|
|
12
|
+
|
|
13
|
+
// The last sequence number the host applied from each stream the consumer reads.
|
|
9
14
|
export async function readOffsets(
|
|
10
15
|
store: StoreReader,
|
|
11
|
-
|
|
12
|
-
): Promise<Result<Offset[],
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
.orderBy('stream')
|
|
18
|
-
.execute(),
|
|
16
|
+
consumer: ConsumerDeclaration,
|
|
17
|
+
): Promise<Result<Offset[], StoreReaderFailure>> {
|
|
18
|
+
const table = sql.table(`${consumer.name}.offsets`);
|
|
19
|
+
|
|
20
|
+
const result = await store.withConsumers([consumer], (db) =>
|
|
21
|
+
sql`select stream, last_seq_num from ${table} order by stream`.execute(db),
|
|
19
22
|
);
|
|
20
23
|
|
|
21
24
|
if (!result.ok) {
|
|
22
25
|
return result;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
const offsets =
|
|
28
|
+
const offsets = offsetRowsSchema
|
|
29
|
+
.parse(result.value)
|
|
30
|
+
.rows.map((row) => ({ stream: row.stream, lastSeqNum: row.last_seq_num }));
|
|
26
31
|
|
|
27
32
|
return { ok: true, value: offsets };
|
|
28
33
|
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { StreamOffset } from '@pepys/kit';
|
|
2
|
-
|
|
3
|
-
export type ChangeMessage =
|
|
4
|
-
| {
|
|
5
|
-
kind: 'change';
|
|
6
|
-
type: string;
|
|
7
|
-
key: string;
|
|
8
|
-
value: unknown;
|
|
9
|
-
oldValue: unknown;
|
|
10
|
-
operation: 'insert' | 'update' | 'delete';
|
|
11
|
-
}
|
|
12
|
-
| { kind: 'snapshot-start' }
|
|
13
|
-
| { kind: 'snapshot-end' };
|
|
14
|
-
|
|
15
|
-
export interface FeedStream {
|
|
16
|
-
consumer: string;
|
|
17
|
-
generation: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export type FeedPosition = StreamOffset | -1 | 'now';
|
|
21
|
-
|
|
22
|
-
export type FeedRead =
|
|
23
|
-
| { kind: 'messages'; messages: readonly ChangeMessage[]; next: StreamOffset; atTail: boolean }
|
|
24
|
-
| { kind: 'closed'; currentGeneration: number }
|
|
25
|
-
| { kind: 'gone'; snapshotAt: StreamOffset };
|
|
26
|
-
|
|
27
|
-
export interface ChangeFeed {
|
|
28
|
-
read: (
|
|
29
|
-
stream: FeedStream,
|
|
30
|
-
from: FeedPosition,
|
|
31
|
-
mode: 'catch-up' | 'long-poll',
|
|
32
|
-
) => Promise<FeedRead>;
|
|
33
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { ConsumerDeclaration, EntityIDParts, EntityViewDeclaration } from '@pepys/kit';
|
|
2
|
-
|
|
3
|
-
export interface EntityConsumer {
|
|
4
|
-
consumer: ConsumerDeclaration;
|
|
5
|
-
entityView: EntityViewDeclaration;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function findEntityConsumer(
|
|
9
|
-
consumers: readonly ConsumerDeclaration[],
|
|
10
|
-
parts: EntityIDParts,
|
|
11
|
-
): EntityConsumer | undefined {
|
|
12
|
-
const kind = `${parts.source}:${parts.kind}`;
|
|
13
|
-
|
|
14
|
-
for (const consumer of consumers) {
|
|
15
|
-
const entityView = consumer.entityViews.find((view) => view.kind === kind);
|
|
16
|
-
|
|
17
|
-
if (entityView !== undefined) {
|
|
18
|
-
return { consumer, entityView };
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return undefined;
|
|
23
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { Result } from '@pepys/kit';
|
|
2
|
-
import type { Selectable } from 'kysely';
|
|
3
|
-
import type { ConsumerDB, StoreReader } from './store-reader.ts';
|
|
4
|
-
|
|
5
|
-
type PullRequestRow = Selectable<ConsumerDB['github_pull_request']>;
|
|
6
|
-
|
|
7
|
-
export function readPullRequests(
|
|
8
|
-
store: StoreReader,
|
|
9
|
-
): Promise<Result<PullRequestRow[], { reason: 'no-current-version' }>> {
|
|
10
|
-
return store.withConsumer('github_pull_request', (transaction) =>
|
|
11
|
-
transaction.selectFrom('github_pull_request').selectAll().orderBy('id').execute(),
|
|
12
|
-
);
|
|
13
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { Result } from '@pepys/kit';
|
|
2
|
-
import type { DB } from '@pepys/schema';
|
|
3
|
-
import type { Transaction } from 'kysely';
|
|
4
|
-
|
|
5
|
-
interface EntityViewRow {
|
|
6
|
-
id: string;
|
|
7
|
-
kind: string;
|
|
8
|
-
title: string;
|
|
9
|
-
url: string;
|
|
10
|
-
actor: string | null;
|
|
11
|
-
updated_at: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// the host creates these two tables in every consumer file, beside the consumer's own
|
|
15
|
-
interface OffsetRow {
|
|
16
|
-
stream: string;
|
|
17
|
-
last_seq_num: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
interface ChangeLogRow {
|
|
21
|
-
batch: number;
|
|
22
|
-
changes: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type ConsumerDB = DB & {
|
|
26
|
-
entity: EntityViewRow;
|
|
27
|
-
offsets: OffsetRow;
|
|
28
|
-
change_log: ChangeLogRow;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export interface StoreReader {
|
|
32
|
-
withConsumer: <Value>(
|
|
33
|
-
consumerName: string,
|
|
34
|
-
work: (transaction: Transaction<ConsumerDB>) => Promise<Value>,
|
|
35
|
-
) => Promise<Result<Value, { reason: 'no-current-version' }>>;
|
|
36
|
-
close: () => Promise<void>;
|
|
37
|
-
}
|