@ponder/client 0.9.0-next.3 → 0.9.0-next.5

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/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
2
2
  export { alias, except, exceptAll, intersect, intersectAll, union, unionAll } from 'drizzle-orm/pg-core';
3
- import { PgRemoteDatabase } from 'drizzle-orm/pg-proxy';
3
+ import { SQLWrapper, QueryWithTypings } from 'drizzle-orm';
4
4
  export { and, asc, avg, avgDistinct, between, count, countDistinct, desc, eq, exists, gt, gte, inArray, isNotNull, isNull, like, lt, lte, max, min, ne, not, notBetween, notExists, notIlike, notInArray, or, relations, sql, sum, sumDistinct } from 'drizzle-orm';
5
+ import { PgRemoteDatabase } from 'drizzle-orm/pg-proxy';
5
6
 
6
7
  declare const setDatabaseSchema: <T extends {
7
8
  [name: string]: unknown;
@@ -18,7 +19,7 @@ type Client<schema extends Schema = Schema> = {
18
19
  /** Query the database. */
19
20
  db: ClientDb<schema>;
20
21
  /** Subscribe to live updates. */
21
- live: <result>(query: (db: ClientDb<schema>) => Promise<result>, onData: (result: result) => void, onError?: (error: Error) => void) => {
22
+ live: <result>(queryFn: (db: ClientDb<schema>) => Promise<result> & SQLWrapper, onData: (result: result) => void, onError?: (error: Error) => void) => {
22
23
  unsubscribe: () => void;
23
24
  };
24
25
  };
@@ -105,6 +106,7 @@ declare const status: drizzle_orm_pg_core.PgTableWithColumns<{
105
106
  };
106
107
  dialect: "pg";
107
108
  }>;
109
+ declare const compileQuery: (query: SQLWrapper | string) => QueryWithTypings;
108
110
  /**
109
111
  * Create a client for querying Ponder apps.
110
112
  *
@@ -123,4 +125,4 @@ declare const createClient: <schema extends Schema>(baseUrl: string, { schema }:
123
125
  schema: schema;
124
126
  }) => Client<schema>;
125
127
 
126
- export { type Client, createClient, setDatabaseSchema, status };
128
+ export { type Client, compileQuery, createClient, setDatabaseSchema, status };
package/dist/index.js CHANGED
@@ -85,13 +85,15 @@ var status = pgTable("_ponder_status", (t) => ({
85
85
  ready: t.boolean().notNull()
86
86
  }));
87
87
  status[Symbol.for("ponder:onchain")] = true;
88
+ var noopDatabase = drizzle(() => Promise.resolve({ rows: [] }), {
89
+ casing: "snake_case"
90
+ });
91
+ var dialect = noopDatabase.dialect;
92
+ var compileQuery = (query) => {
93
+ const sequel = typeof query === "string" ? sql.raw(query) : query.getSQL();
94
+ return dialect.sqlToQuery(sequel);
95
+ };
88
96
  var createClient = (baseUrl, { schema }) => {
89
- const noopDatabase = drizzle(() => Promise.resolve({ rows: [] }), {
90
- schema,
91
- casing: "snake_case"
92
- });
93
- const dialect = noopDatabase.dialect;
94
- const session = noopDatabase.session;
95
97
  let sse;
96
98
  let liveCount = 0;
97
99
  const client = {
@@ -114,11 +116,10 @@ var createClient = (baseUrl, { schema }) => {
114
116
  },
115
117
  { schema, casing: "snake_case" }
116
118
  ),
117
- live: (_query, onData, onError) => {
118
- const query = _query(noopDatabase);
119
- const sequel = typeof query === "string" ? sql.raw(query) : query.getSQL();
120
- const builtQuery = dialect.sqlToQuery(sequel);
121
- if (builtQuery.sql === 'select "chain_id", "block_number", "block_timestamp", "ready" from "_ponder_status"' && builtQuery.params.length === 0) {
119
+ live: (queryFn, onData, onError) => {
120
+ const builtQuery = compileQuery(queryFn(noopDatabase));
121
+ const statusQuery = compileQuery(noopDatabase.select().from(status));
122
+ if (statusQuery.sql === builtQuery.sql && builtQuery.params.length === 0) {
122
123
  const addEventListeners = () => {
123
124
  sse.addEventListener("message", (event) => {
124
125
  const data = JSON.parse(event.data);
@@ -153,7 +154,7 @@ var createClient = (baseUrl, { schema }) => {
153
154
  return client.live(
154
155
  (db) => db.select().from(status),
155
156
  () => {
156
- _query(client.db).then(onData).catch(onError);
157
+ queryFn(client.db).then(onData).catch(onError);
157
158
  },
158
159
  onError
159
160
  );
@@ -169,6 +170,7 @@ export {
169
170
  avg,
170
171
  avgDistinct,
171
172
  between,
173
+ compileQuery,
172
174
  count,
173
175
  countDistinct,
174
176
  createClient,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/setDatabaseSchema.ts"],"sourcesContent":["import { type QueryWithTypings, type SQLWrapper, sql } from \"drizzle-orm\";\nimport { type PgDialect, type PgSession, pgTable } from \"drizzle-orm/pg-core\";\nimport { type PgRemoteDatabase, drizzle } from \"drizzle-orm/pg-proxy\";\n\nconst getEventSource = async () => {\n let SSE: typeof EventSource;\n if (typeof window === \"undefined\") {\n const undici = await import(/* webpackIgnore: true */ \"undici\");\n // @ts-ignore\n SSE = undici.EventSource;\n } else {\n SSE = EventSource;\n }\n\n return SSE;\n};\n\ntype Schema = { [name: string]: unknown };\n\ntype Prettify<T> = {\n [K in keyof T]: T[K];\n} & {};\n\ntype ClientDb<schema extends Schema = Schema> = Prettify<\n Omit<\n PgRemoteDatabase<schema>,\n | \"insert\"\n | \"update\"\n | \"delete\"\n | \"transaction\"\n | \"refreshMaterializedView\"\n | \"_\"\n >\n>;\n\nexport type Client<schema extends Schema = Schema> = {\n /** Query the database. */\n db: ClientDb<schema>;\n /** Subscribe to live updates. */\n live: <result>(\n query: (db: ClientDb<schema>) => Promise<result>,\n onData: (result: result) => void,\n onError?: (error: Error) => void,\n ) => {\n unsubscribe: () => void;\n };\n};\n\nconst getUrl = (\n baseUrl: string,\n method: \"live\" | \"db\" | \"status\",\n query?: QueryWithTypings,\n) => {\n const url = new URL(`${baseUrl}/client/${method}`);\n if (query) {\n url.searchParams.set(\"sql\", JSON.stringify(query));\n }\n return url;\n};\n\n/**\n * A table that tracks the status of each chain.\n *\n * @property {number} chainId - The chain ID.\n * @property {number} blockNumber - The closest-to-tip indexed block number.\n * @property {number} blockTimestamp - The closest-to-tip indexed block timestamp.\n * @property {boolean} ready - `true` if the chain has completed the historical backfill.\n */\nexport const status = pgTable(\"_ponder_status\", (t) => ({\n chainId: t.bigint({ mode: \"number\" }).primaryKey(),\n blockNumber: t.bigint({ mode: \"number\" }),\n blockTimestamp: t.bigint({ mode: \"number\" }),\n ready: t.boolean().notNull(),\n}));\n\n// @ts-ignore\nstatus[Symbol.for(\"ponder:onchain\")] = true;\n\n/**\n * Create a client for querying Ponder apps.\n *\n * @param baseUrl - The URL of the Ponder app.\n * @param schema - The schema of the Ponder app.\n *\n * @example\n * ```ts\n * import { createClient } from \"@ponder/client\";\n * import * as schema from \"../ponder.schema\";\n *\n * const client = createClient(\"https://...\", { schema });\n * ```\n */\nexport const createClient = <schema extends Schema>(\n baseUrl: string,\n { schema }: { schema: schema },\n): Client<schema> => {\n const noopDatabase = drizzle(() => Promise.resolve({ rows: [] }), {\n schema,\n casing: \"snake_case\",\n });\n\n // @ts-ignore\n const dialect: PgDialect = noopDatabase.dialect;\n // @ts-ignore\n const session: PgSession = noopDatabase.session;\n\n let sse: EventSource | undefined;\n let liveCount = 0;\n\n const client: Client<schema> = {\n db: drizzle(\n async (sql, params, _, typings) => {\n const builtQuery = { sql, params, typings };\n const response = await fetch(getUrl(baseUrl, \"db\", builtQuery), {\n method: \"POST\",\n });\n\n if (response.ok === false) {\n const error = new Error(await response.text());\n error.stack = undefined;\n throw error;\n }\n\n const result = await response.json();\n\n return {\n ...result,\n rows: result.rows.map((row: object) => Object.values(row)),\n };\n },\n { schema, casing: \"snake_case\" },\n ),\n live: (_query, onData, onError) => {\n // https://github.com/drizzle-team/drizzle-orm/blob/04c91434c7ac10aeb2923efd1d19a7ebf10ea9d4/drizzle-orm/src/pg-core/db.ts#L602-L621\n\n const query = _query(noopDatabase) as unknown as SQLWrapper | string;\n const sequel =\n typeof query === \"string\" ? sql.raw(query) : query.getSQL();\n const builtQuery = dialect.sqlToQuery(sequel);\n\n if (\n builtQuery.sql ===\n 'select \"chain_id\", \"block_number\", \"block_timestamp\", \"ready\" from \"_ponder_status\"' &&\n builtQuery.params.length === 0\n ) {\n const addEventListeners = () => {\n sse!.addEventListener(\"message\", (event) => {\n const data = JSON.parse(event.data) as\n | { status: \"success\"; result: unknown }\n | { status: \"error\"; error: string };\n\n if (data.status === \"error\") {\n const error = new Error(data.error);\n error.stack = undefined;\n onError?.(error);\n } else {\n // @ts-ignore\n onData(data.result);\n }\n });\n\n sse!.addEventListener(\"error\", () => {\n onError?.(new Error(\"server disconnected\"));\n });\n };\n\n liveCount++;\n if (sse === undefined) {\n getEventSource().then((SSE) => {\n sse = new SSE(getUrl(baseUrl, \"live\"));\n addEventListeners();\n });\n } else {\n addEventListeners();\n }\n\n return {\n unsubscribe: () => {\n if (--liveCount === 0) sse?.close();\n },\n };\n } else {\n return client.live(\n (db) => db.select().from(status),\n () => {\n _query(client.db).then(onData).catch(onError);\n },\n onError,\n );\n }\n },\n };\n\n return client;\n};\n\nexport {\n sql,\n eq,\n gt,\n gte,\n lt,\n lte,\n ne,\n isNull,\n isNotNull,\n inArray,\n notInArray,\n exists,\n notExists,\n between,\n notBetween,\n like,\n notIlike,\n not,\n asc,\n desc,\n and,\n or,\n count,\n countDistinct,\n avg,\n avgDistinct,\n sum,\n sumDistinct,\n max,\n min,\n relations,\n} from \"drizzle-orm\";\n\nexport {\n alias,\n union,\n unionAll,\n intersect,\n intersectAll,\n except,\n exceptAll,\n} from \"drizzle-orm/pg-core\";\n\nexport { setDatabaseSchema } from \"./setDatabaseSchema.js\";\n","import { Table, is } from \"drizzle-orm\";\n\nconst Schema = Symbol.for(\"drizzle:Schema\");\n\nexport const setDatabaseSchema = <T extends { [name: string]: unknown }>(\n schema: T,\n schemaName: string,\n): T => {\n for (const table of Object.values(schema)) {\n if (is(table, Table)) {\n // @ts-ignore\n table[Schema] = schemaName;\n }\n }\n return schema;\n};\n"],"mappings":"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","names":["sql","sql"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/setDatabaseSchema.ts"],"sourcesContent":["import { type QueryWithTypings, type SQLWrapper, sql } from \"drizzle-orm\";\nimport { type PgDialect, pgTable } from \"drizzle-orm/pg-core\";\nimport { type PgRemoteDatabase, drizzle } from \"drizzle-orm/pg-proxy\";\n\nconst getEventSource = async () => {\n let SSE: typeof EventSource;\n if (typeof window === \"undefined\") {\n const undici = await import(/* webpackIgnore: true */ \"undici\");\n // @ts-ignore\n SSE = undici.EventSource;\n } else {\n SSE = EventSource;\n }\n\n return SSE;\n};\n\ntype Schema = { [name: string]: unknown };\n\ntype Prettify<T> = {\n [K in keyof T]: T[K];\n} & {};\n\ntype ClientDb<schema extends Schema = Schema> = Prettify<\n Omit<\n PgRemoteDatabase<schema>,\n | \"insert\"\n | \"update\"\n | \"delete\"\n | \"transaction\"\n | \"refreshMaterializedView\"\n | \"_\"\n >\n>;\n\nexport type Client<schema extends Schema = Schema> = {\n /** Query the database. */\n db: ClientDb<schema>;\n /** Subscribe to live updates. */\n live: <result>(\n queryFn: (db: ClientDb<schema>) => Promise<result> & SQLWrapper,\n onData: (result: result) => void,\n onError?: (error: Error) => void,\n ) => {\n unsubscribe: () => void;\n };\n};\n\nconst getUrl = (\n baseUrl: string,\n method: \"live\" | \"db\" | \"status\",\n query?: QueryWithTypings,\n) => {\n const url = new URL(`${baseUrl}/client/${method}`);\n if (query) {\n url.searchParams.set(\"sql\", JSON.stringify(query));\n }\n return url;\n};\n\n/**\n * A table that tracks the status of each chain.\n *\n * @property {number} chainId - The chain ID.\n * @property {number} blockNumber - The closest-to-tip indexed block number.\n * @property {number} blockTimestamp - The closest-to-tip indexed block timestamp.\n * @property {boolean} ready - `true` if the chain has completed the historical backfill.\n */\nexport const status = pgTable(\"_ponder_status\", (t) => ({\n chainId: t.bigint({ mode: \"number\" }).primaryKey(),\n blockNumber: t.bigint({ mode: \"number\" }),\n blockTimestamp: t.bigint({ mode: \"number\" }),\n ready: t.boolean().notNull(),\n}));\n\n// @ts-ignore\nstatus[Symbol.for(\"ponder:onchain\")] = true;\n\nconst noopDatabase = drizzle(() => Promise.resolve({ rows: [] }), {\n casing: \"snake_case\",\n});\n\n// @ts-ignore\nconst dialect: PgDialect = noopDatabase.dialect;\n\nexport const compileQuery = (query: SQLWrapper | string) => {\n const sequel = typeof query === \"string\" ? sql.raw(query) : query.getSQL();\n return dialect.sqlToQuery(sequel);\n};\n\n/**\n * Create a client for querying Ponder apps.\n *\n * @param baseUrl - The URL of the Ponder app.\n * @param schema - The schema of the Ponder app.\n *\n * @example\n * ```ts\n * import { createClient } from \"@ponder/client\";\n * import * as schema from \"../ponder.schema\";\n *\n * const client = createClient(\"https://...\", { schema });\n * ```\n */\nexport const createClient = <schema extends Schema>(\n baseUrl: string,\n { schema }: { schema: schema },\n): Client<schema> => {\n let sse: EventSource | undefined;\n let liveCount = 0;\n\n const client: Client<schema> = {\n db: drizzle(\n async (sql, params, _, typings) => {\n const builtQuery = { sql, params, typings };\n const response = await fetch(getUrl(baseUrl, \"db\", builtQuery), {\n method: \"POST\",\n });\n\n if (response.ok === false) {\n const error = new Error(await response.text());\n error.stack = undefined;\n throw error;\n }\n\n const result = await response.json();\n\n return {\n ...result,\n rows: result.rows.map((row: object) => Object.values(row)),\n };\n },\n { schema, casing: \"snake_case\" },\n ),\n live: (queryFn, onData, onError) => {\n // https://github.com/drizzle-team/drizzle-orm/blob/04c91434c7ac10aeb2923efd1d19a7ebf10ea9d4/drizzle-orm/src/pg-core/db.ts#L602-L621\n\n // @ts-ignore\n const builtQuery = compileQuery(queryFn(noopDatabase));\n\n const statusQuery = compileQuery(noopDatabase.select().from(status));\n if (\n statusQuery.sql === builtQuery.sql &&\n builtQuery.params.length === 0\n ) {\n const addEventListeners = () => {\n sse!.addEventListener(\"message\", (event) => {\n const data = JSON.parse(event.data) as\n | { status: \"success\"; result: unknown }\n | { status: \"error\"; error: string };\n\n if (data.status === \"error\") {\n const error = new Error(data.error);\n error.stack = undefined;\n onError?.(error);\n } else {\n // @ts-ignore\n onData(data.result);\n }\n });\n\n sse!.addEventListener(\"error\", () => {\n onError?.(new Error(\"server disconnected\"));\n });\n };\n\n liveCount++;\n if (sse === undefined) {\n getEventSource().then((SSE) => {\n sse = new SSE(getUrl(baseUrl, \"live\"));\n addEventListeners();\n });\n } else {\n addEventListeners();\n }\n\n return {\n unsubscribe: () => {\n if (--liveCount === 0) sse?.close();\n },\n };\n } else {\n return client.live(\n (db) => db.select().from(status),\n () => {\n queryFn(client.db).then(onData).catch(onError);\n },\n onError,\n );\n }\n },\n };\n\n return client;\n};\n\nexport {\n sql,\n eq,\n gt,\n gte,\n lt,\n lte,\n ne,\n isNull,\n isNotNull,\n inArray,\n notInArray,\n exists,\n notExists,\n between,\n notBetween,\n like,\n notIlike,\n not,\n asc,\n desc,\n and,\n or,\n count,\n countDistinct,\n avg,\n avgDistinct,\n sum,\n sumDistinct,\n max,\n min,\n relations,\n} from \"drizzle-orm\";\n\nexport {\n alias,\n union,\n unionAll,\n intersect,\n intersectAll,\n except,\n exceptAll,\n} from \"drizzle-orm/pg-core\";\n\nexport { setDatabaseSchema } from \"./setDatabaseSchema.js\";\n","import { Table, is } from \"drizzle-orm\";\n\nconst Schema = Symbol.for(\"drizzle:Schema\");\n\nexport const setDatabaseSchema = <T extends { [name: string]: unknown }>(\n schema: T,\n schemaName: string,\n): T => {\n for (const table of Object.values(schema)) {\n if (is(table, Table)) {\n // @ts-ignore\n table[Schema] = schemaName;\n }\n }\n return schema;\n};\n"],"mappings":"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","names":["sql","sql"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ponder/client",
3
- "version": "0.9.0-next.3",
3
+ "version": "0.9.0-next.5",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type QueryWithTypings, type SQLWrapper, sql } from "drizzle-orm";
2
- import { type PgDialect, type PgSession, pgTable } from "drizzle-orm/pg-core";
2
+ import { type PgDialect, pgTable } from "drizzle-orm/pg-core";
3
3
  import { type PgRemoteDatabase, drizzle } from "drizzle-orm/pg-proxy";
4
4
 
5
5
  const getEventSource = async () => {
@@ -38,7 +38,7 @@ export type Client<schema extends Schema = Schema> = {
38
38
  db: ClientDb<schema>;
39
39
  /** Subscribe to live updates. */
40
40
  live: <result>(
41
- query: (db: ClientDb<schema>) => Promise<result>,
41
+ queryFn: (db: ClientDb<schema>) => Promise<result> & SQLWrapper,
42
42
  onData: (result: result) => void,
43
43
  onError?: (error: Error) => void,
44
44
  ) => {
@@ -76,6 +76,18 @@ export const status = pgTable("_ponder_status", (t) => ({
76
76
  // @ts-ignore
77
77
  status[Symbol.for("ponder:onchain")] = true;
78
78
 
79
+ const noopDatabase = drizzle(() => Promise.resolve({ rows: [] }), {
80
+ casing: "snake_case",
81
+ });
82
+
83
+ // @ts-ignore
84
+ const dialect: PgDialect = noopDatabase.dialect;
85
+
86
+ export const compileQuery = (query: SQLWrapper | string) => {
87
+ const sequel = typeof query === "string" ? sql.raw(query) : query.getSQL();
88
+ return dialect.sqlToQuery(sequel);
89
+ };
90
+
79
91
  /**
80
92
  * Create a client for querying Ponder apps.
81
93
  *
@@ -94,16 +106,6 @@ export const createClient = <schema extends Schema>(
94
106
  baseUrl: string,
95
107
  { schema }: { schema: schema },
96
108
  ): Client<schema> => {
97
- const noopDatabase = drizzle(() => Promise.resolve({ rows: [] }), {
98
- schema,
99
- casing: "snake_case",
100
- });
101
-
102
- // @ts-ignore
103
- const dialect: PgDialect = noopDatabase.dialect;
104
- // @ts-ignore
105
- const session: PgSession = noopDatabase.session;
106
-
107
109
  let sse: EventSource | undefined;
108
110
  let liveCount = 0;
109
111
 
@@ -130,17 +132,15 @@ export const createClient = <schema extends Schema>(
130
132
  },
131
133
  { schema, casing: "snake_case" },
132
134
  ),
133
- live: (_query, onData, onError) => {
135
+ live: (queryFn, onData, onError) => {
134
136
  // https://github.com/drizzle-team/drizzle-orm/blob/04c91434c7ac10aeb2923efd1d19a7ebf10ea9d4/drizzle-orm/src/pg-core/db.ts#L602-L621
135
137
 
136
- const query = _query(noopDatabase) as unknown as SQLWrapper | string;
137
- const sequel =
138
- typeof query === "string" ? sql.raw(query) : query.getSQL();
139
- const builtQuery = dialect.sqlToQuery(sequel);
138
+ // @ts-ignore
139
+ const builtQuery = compileQuery(queryFn(noopDatabase));
140
140
 
141
+ const statusQuery = compileQuery(noopDatabase.select().from(status));
141
142
  if (
142
- builtQuery.sql ===
143
- 'select "chain_id", "block_number", "block_timestamp", "ready" from "_ponder_status"' &&
143
+ statusQuery.sql === builtQuery.sql &&
144
144
  builtQuery.params.length === 0
145
145
  ) {
146
146
  const addEventListeners = () => {
@@ -183,7 +183,7 @@ export const createClient = <schema extends Schema>(
183
183
  return client.live(
184
184
  (db) => db.select().from(status),
185
185
  () => {
186
- _query(client.db).then(onData).catch(onError);
186
+ queryFn(client.db).then(onData).catch(onError);
187
187
  },
188
188
  onError,
189
189
  );