@dbos-inc/postgres-datasource 3.0.11-preview.gc9233b8190 → 3.0.16-preview

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,14 +1,19 @@
1
1
  import postgres from 'postgres';
2
- import { PGIsolationLevel as IsolationLevel, PGTransactionConfig as PostgresTransactionOptions, DBOSDataSource } from '@dbos-inc/dbos-sdk/datasource';
2
+ import { PGIsolationLevel as IsolationLevel, PGTransactionConfig, DBOSDataSource } from '@dbos-inc/dbos-sdk/datasource';
3
+ interface PostgresTransactionOptions extends PGTransactionConfig {
4
+ name?: string;
5
+ }
3
6
  export { IsolationLevel, PostgresTransactionOptions };
7
+ type Options = postgres.Options<{}>;
4
8
  export declare class PostgresDataSource implements DBOSDataSource<PostgresTransactionOptions> {
5
9
  #private;
6
- static get client(): postgres.TransactionSql<{}>;
7
- static initializeInternalSchema(options?: postgres.Options<{}>): Promise<void>;
8
10
  readonly name: string;
9
- constructor(name: string, options?: postgres.Options<{}>);
10
- runTransaction<T>(callback: () => Promise<T>, name: string, config?: PostgresTransactionOptions): Promise<T>;
11
- registerTransaction<This, Args extends unknown[], Return>(func: (this: This, ...args: Args) => Promise<Return>, name: string, config?: PostgresTransactionOptions): (this: This, ...args: Args) => Promise<Return>;
12
- transaction(config?: PostgresTransactionOptions): <This, Args extends unknown[], Return>(_target: object, propertyKey: string, descriptor: TypedPropertyDescriptor<(this: This, ...args: Args) => Promise<Return>>) => TypedPropertyDescriptor<(this: This, ...args: Args) => Promise<Return>>;
11
+ static get client(): postgres.TransactionSql<{}>;
12
+ get client(): postgres.TransactionSql<{}>;
13
+ static initializeDBOSSchema(options?: Options): Promise<void>;
14
+ constructor(name: string, options?: Options);
15
+ runTransaction<T>(func: () => Promise<T>, config?: PostgresTransactionOptions): Promise<T>;
16
+ registerTransaction<This, Args extends unknown[], Return>(func: (this: This, ...args: Args) => Promise<Return>, config?: PostgresTransactionOptions): (this: This, ...args: Args) => Promise<Return>;
17
+ transaction(config?: PostgresTransactionOptions): <This, Args extends unknown[], Return>(_target: object, propertyKey: PropertyKey, descriptor: TypedPropertyDescriptor<(this: This, ...args: Args) => Promise<Return>>) => TypedPropertyDescriptor<(this: This, ...args: Args) => Promise<Return>>;
13
18
  }
14
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAEA,OAAO,QAAsB,MAAM,UAAU,CAAC;AAE9C,OAAO,EAQL,gBAAgB,IAAI,cAAc,EAClC,mBAAmB,IAAI,0BAA0B,EACjD,cAAc,EAEf,MAAM,+BAA+B,CAAC;AAIvC,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC;AA0JtD,qBAAa,kBAAmB,YAAW,cAAc,CAAC,0BAA0B,CAAC;;IAEnF,MAAM,KAAK,MAAM,IAAI,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,CAS/C;WAGY,wBAAwB,CAAC,OAAO,GAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUxF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAIV,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAM;IAMtD,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,0BAA0B;IAIrG,mBAAmB,CAAC,IAAI,EAAE,IAAI,SAAS,OAAO,EAAE,EAAE,MAAM,EACtD,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,EACpD,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,0BAA0B,GAClC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC;IAIjD,WAAW,CAAC,MAAM,CAAC,EAAE,0BAA0B,mDAIlC,MAAM,eACF,MAAM,cACP,wBAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,QAAQ,MAAM,CAAC,CAAC,oCAAxC,IAAI,WAAW,IAAI,KAAK,QAAQ,MAAM,CAAC;CAWvF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAEA,OAAO,QAAsB,MAAM,UAAU,CAAC;AAE9C,OAAO,EAQL,gBAAgB,IAAI,cAAc,EAClC,mBAAmB,EACnB,cAAc,EAEf,MAAM,+BAA+B,CAAC;AAIvC,UAAU,0BAA2B,SAAQ,mBAAmB;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC;AAQtD,KAAK,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAqJpC,qBAAa,kBAAmB,YAAW,cAAc,CAAC,0BAA0B,CAAC;;IAoCjF,QAAQ,CAAC,IAAI,EAAE,MAAM;IArBvB,MAAM,KAAK,MAAM,gCAEhB;IAED,IAAI,MAAM,gCAET;WAEY,oBAAoB,CAAC,OAAO,GAAE,OAAY,GAAG,OAAO,CAAC,IAAI,CAAC;gBAa5D,IAAI,EAAE,MAAM,EACrB,OAAO,GAAE,OAAY;IAMjB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,0BAA0B;IAInF,mBAAmB,CAAC,IAAI,EAAE,IAAI,SAAS,OAAO,EAAE,EAAE,MAAM,EACtD,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,EACpD,MAAM,CAAC,EAAE,0BAA0B,GAClC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC;IAIjD,WAAW,CAAC,MAAM,CAAC,EAAE,0BAA0B,mDAIlC,MAAM,eACF,WAAW,cACZ,wBAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,QAAQ,MAAM,CAAC,CAAC,oCAAxC,IAAI,WAAW,IAAI,KAAK,QAAQ,MAAM,CAAC;CAcvF"}
package/dist/index.js CHANGED
@@ -14,37 +14,44 @@ const superjson_1 = require("superjson");
14
14
  const asyncLocalCtx = new node_async_hooks_1.AsyncLocalStorage();
15
15
  class PostgresTransactionHandler {
16
16
  name;
17
+ options;
17
18
  dsType = 'PostgresDataSource';
18
- #db;
19
- constructor(name,
20
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
21
- options = {}) {
19
+ #dbField;
20
+ constructor(name, options = {}) {
22
21
  this.name = name;
23
- this.#db = (0, postgres_1.default)(options);
22
+ this.options = options;
23
+ }
24
+ async initialize() {
25
+ const db = this.#dbField;
26
+ this.#dbField = (0, postgres_1.default)(this.options);
27
+ await db?.end();
24
28
  }
25
- initialize() {
26
- return Promise.resolve();
29
+ async destroy() {
30
+ const db = this.#dbField;
31
+ this.#dbField = undefined;
32
+ await db?.end();
27
33
  }
28
- destroy() {
29
- return this.#db.end();
34
+ get #db() {
35
+ if (!this.#dbField) {
36
+ throw new Error(`DataSource ${this.name} is not initialized.`);
37
+ }
38
+ return this.#dbField;
30
39
  }
31
- async #checkExecution(workflowID, functionNum) {
40
+ async #checkExecution(workflowID, stepID) {
32
41
  const result = await this.#db `
33
42
  SELECT output, error FROM dbos.transaction_completion
34
- WHERE workflow_id = ${workflowID} AND function_num = ${functionNum}`;
43
+ WHERE workflow_id = ${workflowID} AND function_num = ${stepID}`;
35
44
  if (result.length === 0) {
36
45
  return undefined;
37
46
  }
38
47
  const { output, error } = result[0];
39
48
  return error !== null ? { error } : { output };
40
49
  }
41
- static async #recordOutput(
42
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
43
- client, workflowID, functionNum, output) {
50
+ static async #recordOutput(client, workflowID, stepID, output) {
44
51
  try {
45
52
  await client /*sql*/ `
46
53
  INSERT INTO dbos.transaction_completion (workflow_id, function_num, output)
47
- VALUES (${workflowID}, ${functionNum}, ${output})`;
54
+ VALUES (${workflowID}, ${stepID}, ${output})`;
48
55
  }
49
56
  catch (error) {
50
57
  if ((0, datasource_1.isPGKeyConflictError)(error)) {
@@ -55,11 +62,11 @@ class PostgresTransactionHandler {
55
62
  }
56
63
  }
57
64
  }
58
- async #recordError(workflowID, functionNum, error) {
65
+ async #recordError(workflowID, stepID, error) {
59
66
  try {
60
67
  await this.#db /*sql*/ `
61
68
  INSERT INTO dbos.transaction_completion (workflow_id, function_num, error)
62
- VALUES (${workflowID}, ${functionNum}, ${error})`;
69
+ VALUES (${workflowID}, ${stepID}, ${error})`;
63
70
  }
64
71
  catch (error) {
65
72
  if ((0, datasource_1.isPGKeyConflictError)(error)) {
@@ -72,23 +79,21 @@ class PostgresTransactionHandler {
72
79
  }
73
80
  async invokeTransactionFunction(config, target, func, ...args) {
74
81
  const workflowID = dbos_sdk_1.DBOS.workflowID;
75
- if (workflowID === undefined) {
76
- throw new Error('Workflow ID is not set.');
77
- }
78
- const functionNum = dbos_sdk_1.DBOS.stepID;
79
- if (functionNum === undefined) {
80
- throw new Error('Function Number is not set.');
82
+ const stepID = dbos_sdk_1.DBOS.stepID;
83
+ if (workflowID !== undefined && stepID === undefined) {
84
+ throw new Error('DBOS.stepID is undefined inside a workflow.');
81
85
  }
82
86
  const isolationLevel = config?.isolationLevel ? `ISOLATION LEVEL ${config.isolationLevel}` : '';
83
87
  const readOnly = config?.readOnly ?? false;
84
88
  const accessMode = config?.readOnly === undefined ? '' : readOnly ? 'READ ONLY' : 'READ WRITE';
85
- const saveResults = !readOnly && workflowID;
89
+ const saveResults = !readOnly && workflowID !== undefined;
90
+ // Retry loop if appropriate
86
91
  let retryWaitMS = 1;
87
92
  const backoffFactor = 1.5;
88
- const maxRetryWaitMS = 2000;
93
+ const maxRetryWaitMS = 2000; // Maximum wait 2 seconds.
89
94
  while (true) {
90
95
  // Check to see if this tx has already been executed
91
- const previousResult = saveResults ? await this.#checkExecution(workflowID, functionNum) : undefined;
96
+ const previousResult = saveResults ? await this.#checkExecution(workflowID, stepID) : undefined;
92
97
  if (previousResult) {
93
98
  dbos_sdk_1.DBOS.span?.setAttribute('cached', true);
94
99
  if ('error' in previousResult) {
@@ -99,12 +104,12 @@ class PostgresTransactionHandler {
99
104
  try {
100
105
  const result = await this.#db.begin(`${isolationLevel} ${accessMode}`, async (client) => {
101
106
  // execute user's transaction function
102
- const result = await asyncLocalCtx.run({ client }, async () => {
107
+ const result = await asyncLocalCtx.run({ client, owner: this }, async () => {
103
108
  return (await func.call(target, ...args));
104
109
  });
105
110
  // save the output of read/write transactions
106
111
  if (saveResults) {
107
- await PostgresTransactionHandler.#recordOutput(client, workflowID, functionNum, superjson_1.SuperJSON.stringify(result));
112
+ await PostgresTransactionHandler.#recordOutput(client, workflowID, stepID, superjson_1.SuperJSON.stringify(result));
108
113
  }
109
114
  return result;
110
115
  });
@@ -121,7 +126,7 @@ class PostgresTransactionHandler {
121
126
  else {
122
127
  if (saveResults) {
123
128
  const message = superjson_1.SuperJSON.stringify(error);
124
- await this.#recordError(workflowID, functionNum, message);
129
+ await this.#recordError(workflowID, stepID, message);
125
130
  }
126
131
  throw error;
127
132
  }
@@ -130,19 +135,27 @@ class PostgresTransactionHandler {
130
135
  }
131
136
  }
132
137
  class PostgresDataSource {
133
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
134
- static get client() {
138
+ name;
139
+ static #getClient(p) {
135
140
  if (!dbos_sdk_1.DBOS.isInTransaction()) {
136
- throw new Error('invalid use of PostgresDataSource.client outside of a DBOS transaction.');
141
+ throw new Error('Invalid use of PostgresDataSource.client outside of a DBOS transaction.');
137
142
  }
138
143
  const ctx = asyncLocalCtx.getStore();
139
144
  if (!ctx) {
140
- throw new Error('No async local context found.');
145
+ throw new Error('Invalid use of PostgresDataSource.client outside of a DBOS transaction.');
146
+ }
147
+ if (p && p !== ctx.owner) {
148
+ throw new Error('Invalid retrieval of `PostgresDataSource.client` from the wrong instance.');
141
149
  }
142
150
  return ctx.client;
143
151
  }
144
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
145
- static async initializeInternalSchema(options = {}) {
152
+ static get client() {
153
+ return PostgresDataSource.#getClient(undefined);
154
+ }
155
+ get client() {
156
+ return PostgresDataSource.#getClient(this.#provider);
157
+ }
158
+ static async initializeDBOSSchema(options = {}) {
146
159
  const pg = (0, postgres_1.default)({ ...options, onnotice: () => { } });
147
160
  try {
148
161
  await pg.unsafe(datasource_1.createTransactionCompletionSchemaPG);
@@ -152,19 +165,17 @@ class PostgresDataSource {
152
165
  await pg.end();
153
166
  }
154
167
  }
155
- name;
156
168
  #provider;
157
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
158
169
  constructor(name, options = {}) {
159
170
  this.name = name;
160
171
  this.#provider = new PostgresTransactionHandler(name, options);
161
172
  (0, datasource_1.registerDataSource)(this.#provider);
162
173
  }
163
- async runTransaction(callback, name, config) {
164
- return await (0, datasource_1.runTransaction)(callback, name, { dsName: this.name, config });
174
+ async runTransaction(func, config) {
175
+ return await (0, datasource_1.runTransaction)(func, config?.name ?? func.name, { dsName: this.name, config });
165
176
  }
166
- registerTransaction(func, name, config) {
167
- return (0, datasource_1.registerTransaction)(this.name, func, { name }, config);
177
+ registerTransaction(func, config) {
178
+ return (0, datasource_1.registerTransaction)(this.name, func, { name: config?.name ?? func.name }, config);
168
179
  }
169
180
  transaction(config) {
170
181
  // eslint-disable-next-line @typescript-eslint/no-this-alias
@@ -173,7 +184,10 @@ class PostgresDataSource {
173
184
  if (!descriptor.value) {
174
185
  throw Error('Use of decorator when original method is undefined');
175
186
  }
176
- descriptor.value = ds.registerTransaction(descriptor.value, propertyKey.toString(), config);
187
+ descriptor.value = ds.registerTransaction(descriptor.value, {
188
+ ...config,
189
+ name: config?.name ?? String(propertyKey),
190
+ });
177
191
  return descriptor;
178
192
  };
179
193
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
package/index.ts CHANGED
@@ -11,50 +11,65 @@ import {
11
11
  registerTransaction,
12
12
  runTransaction,
13
13
  PGIsolationLevel as IsolationLevel,
14
- PGTransactionConfig as PostgresTransactionOptions,
14
+ PGTransactionConfig,
15
15
  DBOSDataSource,
16
16
  registerDataSource,
17
17
  } from '@dbos-inc/dbos-sdk/datasource';
18
18
  import { AsyncLocalStorage } from 'node:async_hooks';
19
19
  import { SuperJSON } from 'superjson';
20
20
 
21
+ interface PostgresTransactionOptions extends PGTransactionConfig {
22
+ name?: string;
23
+ }
24
+
21
25
  export { IsolationLevel, PostgresTransactionOptions };
22
26
 
23
27
  interface PostgresDataSourceContext {
24
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
25
- client: postgres.TransactionSql<{}>;
28
+ client: postgres.TransactionSql;
29
+ owner: PostgresTransactionHandler;
26
30
  }
27
31
 
32
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
33
+ type Options = postgres.Options<{}>;
34
+
28
35
  const asyncLocalCtx = new AsyncLocalStorage<PostgresDataSourceContext>();
29
36
 
30
37
  class PostgresTransactionHandler implements DataSourceTransactionHandler {
31
38
  readonly dsType = 'PostgresDataSource';
32
- readonly #db: Sql;
39
+ #dbField: Sql | undefined;
33
40
 
34
41
  constructor(
35
42
  readonly name: string,
36
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
37
- options: postgres.Options<{}> = {},
38
- ) {
39
- this.#db = postgres(options);
43
+ private readonly options: Options = {},
44
+ ) {}
45
+
46
+ async initialize(): Promise<void> {
47
+ const db = this.#dbField;
48
+ this.#dbField = postgres(this.options);
49
+ await db?.end();
40
50
  }
41
51
 
42
- initialize(): Promise<void> {
43
- return Promise.resolve();
52
+ async destroy(): Promise<void> {
53
+ const db = this.#dbField;
54
+ this.#dbField = undefined;
55
+ await db?.end();
44
56
  }
45
57
 
46
- destroy(): Promise<void> {
47
- return this.#db.end();
58
+ get #db(): Sql {
59
+ if (!this.#dbField) {
60
+ throw new Error(`DataSource ${this.name} is not initialized.`);
61
+ }
62
+ return this.#dbField;
48
63
  }
49
64
 
50
65
  async #checkExecution(
51
66
  workflowID: string,
52
- functionNum: number,
67
+ stepID: number,
53
68
  ): Promise<{ output: string | null } | { error: string } | undefined> {
54
69
  type Result = { output: string | null; error: string | null };
55
70
  const result = await this.#db<Result[]>/*sql*/ `
56
71
  SELECT output, error FROM dbos.transaction_completion
57
- WHERE workflow_id = ${workflowID} AND function_num = ${functionNum}`;
72
+ WHERE workflow_id = ${workflowID} AND function_num = ${stepID}`;
58
73
  if (result.length === 0) {
59
74
  return undefined;
60
75
  }
@@ -63,16 +78,15 @@ class PostgresTransactionHandler implements DataSourceTransactionHandler {
63
78
  }
64
79
 
65
80
  static async #recordOutput(
66
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
67
- client: postgres.TransactionSql<{}>,
81
+ client: postgres.TransactionSql,
68
82
  workflowID: string,
69
- functionNum: number,
83
+ stepID: number,
70
84
  output: string | null,
71
85
  ): Promise<void> {
72
86
  try {
73
87
  await client/*sql*/ `
74
88
  INSERT INTO dbos.transaction_completion (workflow_id, function_num, output)
75
- VALUES (${workflowID}, ${functionNum}, ${output})`;
89
+ VALUES (${workflowID}, ${stepID}, ${output})`;
76
90
  } catch (error) {
77
91
  if (isPGKeyConflictError(error)) {
78
92
  throw new DBOSWorkflowConflictError(workflowID);
@@ -82,11 +96,11 @@ class PostgresTransactionHandler implements DataSourceTransactionHandler {
82
96
  }
83
97
  }
84
98
 
85
- async #recordError(workflowID: string, functionNum: number, error: string): Promise<void> {
99
+ async #recordError(workflowID: string, stepID: number, error: string): Promise<void> {
86
100
  try {
87
101
  await this.#db/*sql*/ `
88
102
  INSERT INTO dbos.transaction_completion (workflow_id, function_num, error)
89
- VALUES (${workflowID}, ${functionNum}, ${error})`;
103
+ VALUES (${workflowID}, ${stepID}, ${error})`;
90
104
  } catch (error) {
91
105
  if (isPGKeyConflictError(error)) {
92
106
  throw new DBOSWorkflowConflictError(workflowID);
@@ -103,26 +117,24 @@ class PostgresTransactionHandler implements DataSourceTransactionHandler {
103
117
  ...args: Args
104
118
  ): Promise<Return> {
105
119
  const workflowID = DBOS.workflowID;
106
- if (workflowID === undefined) {
107
- throw new Error('Workflow ID is not set.');
108
- }
109
- const functionNum = DBOS.stepID;
110
- if (functionNum === undefined) {
111
- throw new Error('Function Number is not set.');
120
+ const stepID = DBOS.stepID;
121
+ if (workflowID !== undefined && stepID === undefined) {
122
+ throw new Error('DBOS.stepID is undefined inside a workflow.');
112
123
  }
113
124
 
114
125
  const isolationLevel = config?.isolationLevel ? `ISOLATION LEVEL ${config.isolationLevel}` : '';
115
126
  const readOnly = config?.readOnly ?? false;
116
127
  const accessMode = config?.readOnly === undefined ? '' : readOnly ? 'READ ONLY' : 'READ WRITE';
117
- const saveResults = !readOnly && workflowID;
128
+ const saveResults = !readOnly && workflowID !== undefined;
118
129
 
130
+ // Retry loop if appropriate
119
131
  let retryWaitMS = 1;
120
132
  const backoffFactor = 1.5;
121
- const maxRetryWaitMS = 2000;
133
+ const maxRetryWaitMS = 2000; // Maximum wait 2 seconds.
122
134
 
123
135
  while (true) {
124
136
  // Check to see if this tx has already been executed
125
- const previousResult = saveResults ? await this.#checkExecution(workflowID, functionNum) : undefined;
137
+ const previousResult = saveResults ? await this.#checkExecution(workflowID, stepID!) : undefined;
126
138
  if (previousResult) {
127
139
  DBOS.span?.setAttribute('cached', true);
128
140
 
@@ -135,18 +147,13 @@ class PostgresTransactionHandler implements DataSourceTransactionHandler {
135
147
  try {
136
148
  const result = await this.#db.begin<Return>(`${isolationLevel} ${accessMode}`, async (client) => {
137
149
  // execute user's transaction function
138
- const result = await asyncLocalCtx.run({ client }, async () => {
150
+ const result = await asyncLocalCtx.run({ client, owner: this }, async () => {
139
151
  return (await func.call(target, ...args)) as Return;
140
152
  });
141
153
 
142
154
  // save the output of read/write transactions
143
155
  if (saveResults) {
144
- await PostgresTransactionHandler.#recordOutput(
145
- client,
146
- workflowID,
147
- functionNum,
148
- SuperJSON.stringify(result),
149
- );
156
+ await PostgresTransactionHandler.#recordOutput(client, workflowID, stepID!, SuperJSON.stringify(result));
150
157
  }
151
158
 
152
159
  return result;
@@ -162,7 +169,7 @@ class PostgresTransactionHandler implements DataSourceTransactionHandler {
162
169
  } else {
163
170
  if (saveResults) {
164
171
  const message = SuperJSON.stringify(error);
165
- await this.#recordError(workflowID, functionNum, message);
172
+ await this.#recordError(workflowID, stepID!, message);
166
173
  }
167
174
 
168
175
  throw error;
@@ -173,20 +180,29 @@ class PostgresTransactionHandler implements DataSourceTransactionHandler {
173
180
  }
174
181
 
175
182
  export class PostgresDataSource implements DBOSDataSource<PostgresTransactionOptions> {
176
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
177
- static get client(): postgres.TransactionSql<{}> {
183
+ static #getClient(p?: PostgresTransactionHandler): postgres.TransactionSql {
178
184
  if (!DBOS.isInTransaction()) {
179
- throw new Error('invalid use of PostgresDataSource.client outside of a DBOS transaction.');
185
+ throw new Error('Invalid use of PostgresDataSource.client outside of a DBOS transaction.');
180
186
  }
181
187
  const ctx = asyncLocalCtx.getStore();
182
188
  if (!ctx) {
183
- throw new Error('No async local context found.');
189
+ throw new Error('Invalid use of PostgresDataSource.client outside of a DBOS transaction.');
190
+ }
191
+ if (p && p !== ctx.owner) {
192
+ throw new Error('Invalid retrieval of `PostgresDataSource.client` from the wrong instance.');
184
193
  }
185
194
  return ctx.client;
186
195
  }
187
196
 
188
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
189
- static async initializeInternalSchema(options: postgres.Options<{}> = {}): Promise<void> {
197
+ static get client() {
198
+ return PostgresDataSource.#getClient(undefined);
199
+ }
200
+
201
+ get client() {
202
+ return PostgresDataSource.#getClient(this.#provider);
203
+ }
204
+
205
+ static async initializeDBOSSchema(options: Options = {}): Promise<void> {
190
206
  const pg = postgres({ ...options, onnotice: () => {} });
191
207
  try {
192
208
  await pg.unsafe(createTransactionCompletionSchemaPG);
@@ -196,26 +212,25 @@ export class PostgresDataSource implements DBOSDataSource<PostgresTransactionOpt
196
212
  }
197
213
  }
198
214
 
199
- readonly name: string;
200
215
  #provider: PostgresTransactionHandler;
201
216
 
202
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
203
- constructor(name: string, options: postgres.Options<{}> = {}) {
204
- this.name = name;
217
+ constructor(
218
+ readonly name: string,
219
+ options: Options = {},
220
+ ) {
205
221
  this.#provider = new PostgresTransactionHandler(name, options);
206
222
  registerDataSource(this.#provider);
207
223
  }
208
224
 
209
- async runTransaction<T>(callback: () => Promise<T>, name: string, config?: PostgresTransactionOptions) {
210
- return await runTransaction(callback, name, { dsName: this.name, config });
225
+ async runTransaction<T>(func: () => Promise<T>, config?: PostgresTransactionOptions) {
226
+ return await runTransaction(func, config?.name ?? func.name, { dsName: this.name, config });
211
227
  }
212
228
 
213
229
  registerTransaction<This, Args extends unknown[], Return>(
214
230
  func: (this: This, ...args: Args) => Promise<Return>,
215
- name: string,
216
231
  config?: PostgresTransactionOptions,
217
232
  ): (this: This, ...args: Args) => Promise<Return> {
218
- return registerTransaction(this.name, func, { name }, config);
233
+ return registerTransaction(this.name, func, { name: config?.name ?? func.name }, config);
219
234
  }
220
235
 
221
236
  transaction(config?: PostgresTransactionOptions) {
@@ -223,14 +238,17 @@ export class PostgresDataSource implements DBOSDataSource<PostgresTransactionOpt
223
238
  const ds = this;
224
239
  return function decorator<This, Args extends unknown[], Return>(
225
240
  _target: object,
226
- propertyKey: string,
241
+ propertyKey: PropertyKey,
227
242
  descriptor: TypedPropertyDescriptor<(this: This, ...args: Args) => Promise<Return>>,
228
243
  ) {
229
244
  if (!descriptor.value) {
230
245
  throw Error('Use of decorator when original method is undefined');
231
246
  }
232
247
 
233
- descriptor.value = ds.registerTransaction(descriptor.value, propertyKey.toString(), config);
248
+ descriptor.value = ds.registerTransaction(descriptor.value, {
249
+ ...config,
250
+ name: config?.name ?? String(propertyKey),
251
+ });
234
252
 
235
253
  return descriptor;
236
254
  };
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@dbos-inc/postgres-datasource",
3
- "version": "3.0.11-preview.gc9233b8190",
4
- "description": "",
3
+ "version": "3.0.16-preview",
4
+ "description": "DBOS DataSource library for Postgres database client",
5
5
  "license": "MIT",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "homepage": "https://docs.dbos.dev/",
6
9
  "repository": {
7
10
  "type": "git",
8
11
  "url": "https://github.com/dbos-inc/dbos-transact-ts",
9
- "directory": "packages/knex-datasource"
12
+ "directory": "packages/postgres-datasource"
10
13
  },
11
- "homepage": "https://docs.dbos.dev/",
12
- "main": "index.js",
13
14
  "scripts": {
14
15
  "build": "tsc --project tsconfig.json",
15
16
  "test": "jest --detectOpenHandles"
@@ -17,7 +17,7 @@ describe('PostgresDataSource.configure', () => {
17
17
  });
18
18
 
19
19
  test('configure creates tx outputs table', async () => {
20
- await PostgresDataSource.initializeInternalSchema(config);
20
+ await PostgresDataSource.initializeDBOSSchema(config);
21
21
 
22
22
  const client = new Client(config);
23
23
  try {