@chaos-overlords/storage 0.9.9 → 0.9.10
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/dist/node/index.d.ts +7 -0
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +2 -0
- package/dist/node/index.js.map +1 -1
- package/dist/postgres/index.d.ts +1 -0
- package/dist/postgres/index.d.ts.map +1 -1
- package/dist/postgres/index.js +1 -0
- package/dist/postgres/index.js.map +1 -1
- package/dist/postgres/rateLimits.d.ts +19 -0
- package/dist/postgres/rateLimits.d.ts.map +1 -0
- package/dist/postgres/rateLimits.js +73 -0
- package/dist/postgres/rateLimits.js.map +1 -0
- package/dist/postgres/schema.d.ts +99 -0
- package/dist/postgres/schema.d.ts.map +1 -1
- package/dist/postgres/schema.js +22 -2
- package/dist/postgres/schema.js.map +1 -1
- package/migrations/postgres/0007_cultured_mongu.sql +9 -0
- package/migrations/postgres/meta/0007_snapshot.json +1001 -0
- package/migrations/postgres/meta/_journal.json +7 -0
- package/package.json +4 -4
package/dist/node/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { MultiplayerStorage } from '@chaos-overlords/kernel';
|
|
2
|
+
import { type SweepableRateLimitStore } from '../postgres/rateLimits';
|
|
2
3
|
/** Migration folders, resolved from the package so a runtime never guesses a relative path. */
|
|
3
4
|
export declare const SQLITE_MIGRATIONS_DIR: string;
|
|
4
5
|
export declare const POSTGRES_MIGRATIONS_DIR: string;
|
|
@@ -10,6 +11,11 @@ export interface OpenedStorage {
|
|
|
10
11
|
* (the retention batch above all) by this.
|
|
11
12
|
*/
|
|
12
13
|
dialect: 'sqlite' | 'postgres';
|
|
14
|
+
/**
|
|
15
|
+
* Rate limit windows every process on this database shares, when the database can be shared.
|
|
16
|
+
* Postgres has one; a SQLite file belongs to one process, which counts in memory.
|
|
17
|
+
*/
|
|
18
|
+
rateLimits?: SweepableRateLimitStore;
|
|
13
19
|
close(): Promise<void>;
|
|
14
20
|
}
|
|
15
21
|
/**
|
|
@@ -27,6 +33,7 @@ export declare function openSqliteStorage(filename: string): OpenedStorage;
|
|
|
27
33
|
* the pool would have recovered from on the next query.
|
|
28
34
|
*/
|
|
29
35
|
export declare function openPostgresStorage(connectionString: string, onPoolError?: (error: unknown) => void): Promise<OpenedStorage>;
|
|
36
|
+
export type { SweepableRateLimitStore };
|
|
30
37
|
export type StorageTarget = {
|
|
31
38
|
kind: 'sqlite';
|
|
32
39
|
filename: string;
|
package/dist/node/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAOjE,OAAO,EAA0B,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAM7F,+FAA+F;AAC/F,eAAO,MAAM,qBAAqB,QAEjC,CAAA;AACD,eAAO,MAAM,uBAAuB,QAEnC,CAAA;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,kBAAkB,CAAA;IAC3B;;;;OAIG;IACH,OAAO,EAAE,QAAQ,GAAG,UAAU,CAAA;IAC9B;;;OAGG;IACH,UAAU,CAAC,EAAE,uBAAuB,CAAA;IACpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AASD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAiBjE;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,gBAAgB,EAAE,MAAM,EACxB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GACrC,OAAO,CAAC,aAAa,CAAC,CAyBxB;AAED,YAAY,EAAE,uBAAuB,EAAE,CAAA;AAEvC,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAAA;AAElD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAUrE;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,aAAa,EACrB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GACrC,OAAO,CAAC,aAAa,CAAC,CAIxB"}
|
package/dist/node/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { migrate as migrateSqlite } from 'drizzle-orm/better-sqlite3/migrator';
|
|
|
6
6
|
import { drizzle as drizzlePostgres } from 'drizzle-orm/node-postgres';
|
|
7
7
|
import { migrate as migratePostgres } from 'drizzle-orm/node-postgres/migrator';
|
|
8
8
|
import pg from 'pg';
|
|
9
|
+
import { postgresRateLimitStore } from '../postgres/rateLimits';
|
|
9
10
|
import { createPostgresStorage } from '../postgres/repositories';
|
|
10
11
|
import * as postgresSchema from '../postgres/schema';
|
|
11
12
|
import { createSqliteStorage } from '../sqlite/repositories';
|
|
@@ -73,6 +74,7 @@ export async function openPostgresStorage(connectionString, onPoolError) {
|
|
|
73
74
|
return {
|
|
74
75
|
storage: createPostgresStorage(db),
|
|
75
76
|
dialect: 'postgres',
|
|
77
|
+
rateLimits: postgresRateLimitStore(db),
|
|
76
78
|
close: () => pool.end(),
|
|
77
79
|
};
|
|
78
80
|
}
|
package/dist/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAE7C,OAAO,aAAa,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qCAAqC,CAAA;AAC9E,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,2BAA2B,CAAA;AACtE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,oCAAoC,CAAA;AAC/E,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,KAAK,cAAc,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,KAAK,YAAY,MAAM,kBAAkB,CAAA;AAEhD,+FAA+F;AAC/F,MAAM,CAAC,MAAM,qBAAqB,GAAG,aAAa,CAChD,IAAI,GAAG,CAAC,yBAAyB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CACpD,CAAA;AACD,MAAM,CAAC,MAAM,uBAAuB,GAAG,aAAa,CAClD,IAAI,GAAG,CAAC,2BAA2B,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CACtD,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"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"}
|
package/dist/postgres/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/postgres/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAC7E,OAAO,KAAK,cAAc,MAAM,UAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/postgres/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAC7E,OAAO,KAAK,cAAc,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,sBAAsB,EAAE,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAA"}
|
package/dist/postgres/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/postgres/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAyB,MAAM,gBAAgB,CAAA;AAC7E,OAAO,KAAK,cAAc,MAAM,UAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/postgres/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAyB,MAAM,gBAAgB,CAAA;AAC7E,OAAO,KAAK,cAAc,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,sBAAsB,EAAgC,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { RateLimitStore } from '@chaos-overlords/kernel';
|
|
2
|
+
import type { PostgresDatabase } from './database';
|
|
3
|
+
/** A {@link RateLimitStore} that can also delete the windows that have rolled. */
|
|
4
|
+
export interface SweepableRateLimitStore extends RateLimitStore {
|
|
5
|
+
/** Deletes up to `limit` windows that rolled at or before `now`; returns how many went. */
|
|
6
|
+
sweep(now: number, limit?: number): Promise<number>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Rate limit windows in a Postgres table, so every Node instance on one database spends the same
|
|
10
|
+
* budgets.
|
|
11
|
+
*
|
|
12
|
+
* `consume` is one `INSERT … ON CONFLICT DO UPDATE`: Postgres locks the conflicting row for the
|
|
13
|
+
* update, so concurrent calls from any number of instances are counted one after another, and the
|
|
14
|
+
* decision comes back in the same round trip. Every expression in the `SET` list reads the row as it
|
|
15
|
+
* was before the statement, which is what lets `allowed` record whether this call found room. The
|
|
16
|
+
* rules are the kernel's `consumeWindow`, written in SQL.
|
|
17
|
+
*/
|
|
18
|
+
export declare function postgresRateLimitStore(db: PostgresDatabase): SweepableRateLimitStore;
|
|
19
|
+
//# sourceMappingURL=rateLimits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimits.d.ts","sourceRoot":"","sources":["../../src/postgres/rateLimits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,cAAc,EAAmB,MAAM,yBAAyB,CAAA;AAE/F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAGlD,kFAAkF;AAClF,MAAM,WAAW,uBAAwB,SAAQ,cAAc;IAC7D,2FAA2F;IAC3F,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACpD;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,gBAAgB,GAAG,uBAAuB,CA6DpF"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { and, eq, gt, inArray, lte, sql } from 'drizzle-orm';
|
|
2
|
+
import { rateLimitWindows } from './schema';
|
|
3
|
+
/**
|
|
4
|
+
* Rate limit windows in a Postgres table, so every Node instance on one database spends the same
|
|
5
|
+
* budgets.
|
|
6
|
+
*
|
|
7
|
+
* `consume` is one `INSERT … ON CONFLICT DO UPDATE`: Postgres locks the conflicting row for the
|
|
8
|
+
* update, so concurrent calls from any number of instances are counted one after another, and the
|
|
9
|
+
* decision comes back in the same round trip. Every expression in the `SET` list reads the row as it
|
|
10
|
+
* was before the statement, which is what lets `allowed` record whether this call found room. The
|
|
11
|
+
* rules are the kernel's `consumeWindow`, written in SQL.
|
|
12
|
+
*/
|
|
13
|
+
export function postgresRateLimitStore(db) {
|
|
14
|
+
const t = rateLimitWindows;
|
|
15
|
+
return {
|
|
16
|
+
async consume(key, policy, now) {
|
|
17
|
+
const rolled = sql `${t.resetAt} <= ${now}`;
|
|
18
|
+
const rows = await db
|
|
19
|
+
.insert(t)
|
|
20
|
+
.values({ key, windowStart: now, resetAt: now + policy.windowMs, count: 1, allowed: true })
|
|
21
|
+
.onConflictDoUpdate({
|
|
22
|
+
target: t.key,
|
|
23
|
+
set: {
|
|
24
|
+
allowed: sql `(${rolled} or ${t.count} < ${policy.limit})`,
|
|
25
|
+
windowStart: sql `case when ${rolled} then ${now} else ${t.windowStart} end`,
|
|
26
|
+
resetAt: sql `case when ${rolled} then ${now + policy.windowMs} else ${t.resetAt} end`,
|
|
27
|
+
count: sql `case when ${rolled} then 1 when ${t.count} < ${policy.limit} then ${t.count} + 1 else ${t.count} end`,
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
.returning({
|
|
31
|
+
allowed: t.allowed,
|
|
32
|
+
count: t.count,
|
|
33
|
+
windowStart: t.windowStart,
|
|
34
|
+
resetAt: t.resetAt,
|
|
35
|
+
});
|
|
36
|
+
const row = rows[0];
|
|
37
|
+
if (!row)
|
|
38
|
+
throw new Error('rate limit upsert returned no row');
|
|
39
|
+
return row;
|
|
40
|
+
},
|
|
41
|
+
async inspect(key, now) {
|
|
42
|
+
const rows = await db
|
|
43
|
+
.select({ count: t.count, resetAt: t.resetAt })
|
|
44
|
+
.from(t)
|
|
45
|
+
.where(and(eq(t.key, key), gt(t.resetAt, now)));
|
|
46
|
+
return rows[0] ?? null;
|
|
47
|
+
},
|
|
48
|
+
async refund(key, windowStart) {
|
|
49
|
+
await db
|
|
50
|
+
.update(t)
|
|
51
|
+
.set({ count: sql `${t.count} - 1` })
|
|
52
|
+
.where(and(eq(t.key, key), eq(t.windowStart, windowStart), gt(t.count, 0)));
|
|
53
|
+
},
|
|
54
|
+
/**
|
|
55
|
+
* Batched, so a sweep after a flood of distinct addresses is many short statements rather than
|
|
56
|
+
* one that holds row locks every `consume` is waiting on.
|
|
57
|
+
*/
|
|
58
|
+
async sweep(now, limit = 1000) {
|
|
59
|
+
const doomed = db
|
|
60
|
+
.select({ key: t.key })
|
|
61
|
+
.from(t)
|
|
62
|
+
.where(lte(t.resetAt, now))
|
|
63
|
+
.orderBy(t.resetAt)
|
|
64
|
+
.limit(limit);
|
|
65
|
+
const deleted = await db
|
|
66
|
+
.delete(t)
|
|
67
|
+
.where(and(inArray(t.key, doomed), lte(t.resetAt, now)))
|
|
68
|
+
.returning({ key: t.key });
|
|
69
|
+
return deleted.length;
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=rateLimits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimits.js","sourceRoot":"","sources":["../../src/postgres/rateLimits.ts"],"names":[],"mappings":"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"}
|
|
@@ -1338,4 +1338,103 @@ export declare const takeoverVotes: import("drizzle-orm/pg-core").PgTableWithCol
|
|
|
1338
1338
|
};
|
|
1339
1339
|
dialect: 'pg';
|
|
1340
1340
|
}>;
|
|
1341
|
+
/**
|
|
1342
|
+
* The rate limit windows every Node instance on this database shares; see `PostgresRateLimitStore`.
|
|
1343
|
+
*
|
|
1344
|
+
* One row per budget and caller, holding the window that caller is spending. Postgres only: a SQLite
|
|
1345
|
+
* file is opened by one process, which counts in memory. Times are epoch milliseconds from the
|
|
1346
|
+
* instances' clocks, the same clock the in-process limiter reads.
|
|
1347
|
+
*/
|
|
1348
|
+
export declare const rateLimitWindows: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
1349
|
+
name: "rate_limit_windows";
|
|
1350
|
+
schema: undefined;
|
|
1351
|
+
columns: {
|
|
1352
|
+
key: import("drizzle-orm/pg-core").PgColumn<{
|
|
1353
|
+
name: "key";
|
|
1354
|
+
tableName: "rate_limit_windows";
|
|
1355
|
+
dataType: "string";
|
|
1356
|
+
columnType: "PgText";
|
|
1357
|
+
data: string;
|
|
1358
|
+
driverParam: string;
|
|
1359
|
+
notNull: true;
|
|
1360
|
+
hasDefault: false;
|
|
1361
|
+
isPrimaryKey: true;
|
|
1362
|
+
isAutoincrement: false;
|
|
1363
|
+
hasRuntimeDefault: false;
|
|
1364
|
+
enumValues: [string, ...string[]];
|
|
1365
|
+
baseColumn: never;
|
|
1366
|
+
identity: undefined;
|
|
1367
|
+
generated: undefined;
|
|
1368
|
+
}, {}, {}>;
|
|
1369
|
+
windowStart: import("drizzle-orm/pg-core").PgColumn<{
|
|
1370
|
+
name: "window_start";
|
|
1371
|
+
tableName: "rate_limit_windows";
|
|
1372
|
+
dataType: "number";
|
|
1373
|
+
columnType: "PgBigInt53";
|
|
1374
|
+
data: number;
|
|
1375
|
+
driverParam: string | number;
|
|
1376
|
+
notNull: true;
|
|
1377
|
+
hasDefault: false;
|
|
1378
|
+
isPrimaryKey: false;
|
|
1379
|
+
isAutoincrement: false;
|
|
1380
|
+
hasRuntimeDefault: false;
|
|
1381
|
+
enumValues: undefined;
|
|
1382
|
+
baseColumn: never;
|
|
1383
|
+
identity: undefined;
|
|
1384
|
+
generated: undefined;
|
|
1385
|
+
}, {}, {}>;
|
|
1386
|
+
resetAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
1387
|
+
name: "reset_at";
|
|
1388
|
+
tableName: "rate_limit_windows";
|
|
1389
|
+
dataType: "number";
|
|
1390
|
+
columnType: "PgBigInt53";
|
|
1391
|
+
data: number;
|
|
1392
|
+
driverParam: string | number;
|
|
1393
|
+
notNull: true;
|
|
1394
|
+
hasDefault: false;
|
|
1395
|
+
isPrimaryKey: false;
|
|
1396
|
+
isAutoincrement: false;
|
|
1397
|
+
hasRuntimeDefault: false;
|
|
1398
|
+
enumValues: undefined;
|
|
1399
|
+
baseColumn: never;
|
|
1400
|
+
identity: undefined;
|
|
1401
|
+
generated: undefined;
|
|
1402
|
+
}, {}, {}>;
|
|
1403
|
+
count: import("drizzle-orm/pg-core").PgColumn<{
|
|
1404
|
+
name: "count";
|
|
1405
|
+
tableName: "rate_limit_windows";
|
|
1406
|
+
dataType: "number";
|
|
1407
|
+
columnType: "PgInteger";
|
|
1408
|
+
data: number;
|
|
1409
|
+
driverParam: string | number;
|
|
1410
|
+
notNull: true;
|
|
1411
|
+
hasDefault: false;
|
|
1412
|
+
isPrimaryKey: false;
|
|
1413
|
+
isAutoincrement: false;
|
|
1414
|
+
hasRuntimeDefault: false;
|
|
1415
|
+
enumValues: undefined;
|
|
1416
|
+
baseColumn: never;
|
|
1417
|
+
identity: undefined;
|
|
1418
|
+
generated: undefined;
|
|
1419
|
+
}, {}, {}>;
|
|
1420
|
+
allowed: import("drizzle-orm/pg-core").PgColumn<{
|
|
1421
|
+
name: "allowed";
|
|
1422
|
+
tableName: "rate_limit_windows";
|
|
1423
|
+
dataType: "boolean";
|
|
1424
|
+
columnType: "PgBoolean";
|
|
1425
|
+
data: boolean;
|
|
1426
|
+
driverParam: boolean;
|
|
1427
|
+
notNull: true;
|
|
1428
|
+
hasDefault: false;
|
|
1429
|
+
isPrimaryKey: false;
|
|
1430
|
+
isAutoincrement: false;
|
|
1431
|
+
hasRuntimeDefault: false;
|
|
1432
|
+
enumValues: undefined;
|
|
1433
|
+
baseColumn: never;
|
|
1434
|
+
identity: undefined;
|
|
1435
|
+
generated: undefined;
|
|
1436
|
+
}, {}, {}>;
|
|
1437
|
+
};
|
|
1438
|
+
dialect: 'pg';
|
|
1439
|
+
}>;
|
|
1341
1440
|
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/postgres/schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/postgres/schema.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCnB,CAAA;AAED,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBnB,CAAA;AAED,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmCjB,CAAA;AAED,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EActB,CAAA;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAavB,CAAA;AAED,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBrB,CAAA;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwBvB,CAAA;AAED,yEAAyE;AACzE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAa3B,CAAA;AAED,oFAAoF;AACpF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYzB,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAY5B,CAAA"}
|
package/dist/postgres/schema.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { boolean, index, integer, jsonb, pgTable, primaryKey, text, timestamp, uniqueIndex, } from 'drizzle-orm/pg-core';
|
|
2
|
-
/**
|
|
1
|
+
import { bigint, boolean, index, integer, jsonb, pgTable, primaryKey, text, timestamp, uniqueIndex, } from 'drizzle-orm/pg-core';
|
|
2
|
+
/**
|
|
3
|
+
* The Postgres dialect. Column-for-column the SQLite schema, see that file for the layout notes,
|
|
4
|
+
* except for `rate_limit_windows`, which only a deployment of several instances needs.
|
|
5
|
+
*/
|
|
3
6
|
const stamp = (name) => timestamp(name, { withTimezone: true, mode: 'date' });
|
|
4
7
|
export const matches = pgTable('matches', {
|
|
5
8
|
id: text('id').primaryKey(),
|
|
@@ -155,4 +158,21 @@ export const takeoverVotes = pgTable('takeover_votes', {
|
|
|
155
158
|
decision: text('decision').notNull(),
|
|
156
159
|
castAt: stamp('cast_at').notNull(),
|
|
157
160
|
}, (table) => [primaryKey({ columns: [table.matchId, table.targetPlayerId, table.voterPlayerId] })]);
|
|
161
|
+
/**
|
|
162
|
+
* The rate limit windows every Node instance on this database shares; see `PostgresRateLimitStore`.
|
|
163
|
+
*
|
|
164
|
+
* One row per budget and caller, holding the window that caller is spending. Postgres only: a SQLite
|
|
165
|
+
* file is opened by one process, which counts in memory. Times are epoch milliseconds from the
|
|
166
|
+
* instances' clocks, the same clock the in-process limiter reads.
|
|
167
|
+
*/
|
|
168
|
+
export const rateLimitWindows = pgTable('rate_limit_windows', {
|
|
169
|
+
key: text('key').primaryKey(),
|
|
170
|
+
windowStart: bigint('window_start', { mode: 'number' }).notNull(),
|
|
171
|
+
resetAt: bigint('reset_at', { mode: 'number' }).notNull(),
|
|
172
|
+
count: integer('count').notNull(),
|
|
173
|
+
/** Whether the last call against this window was counted; read back by the same statement. */
|
|
174
|
+
allowed: boolean('allowed').notNull(),
|
|
175
|
+
},
|
|
176
|
+
// The sweep deletes rolled windows in `reset_at` order.
|
|
177
|
+
(table) => [index('rate_limit_windows_reset_idx').on(table.resetAt)]);
|
|
158
178
|
//# sourceMappingURL=schema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/postgres/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,EACL,OAAO,EACP,KAAK,EACL,OAAO,EACP,UAAU,EACV,IAAI,EACJ,SAAS,EACT,WAAW,GACZ,MAAM,qBAAqB,CAAA;AAE5B
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/postgres/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
CREATE TABLE "rate_limit_windows" (
|
|
2
|
+
"key" text PRIMARY KEY NOT NULL,
|
|
3
|
+
"window_start" bigint NOT NULL,
|
|
4
|
+
"reset_at" bigint NOT NULL,
|
|
5
|
+
"count" integer NOT NULL,
|
|
6
|
+
"allowed" boolean NOT NULL
|
|
7
|
+
);
|
|
8
|
+
--> statement-breakpoint
|
|
9
|
+
CREATE INDEX "rate_limit_windows_reset_idx" ON "rate_limit_windows" USING btree ("reset_at");
|