@sentio/sdk 2.39.3 → 2.39.4-rc.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.
Files changed (47) hide show
  1. package/lib/eth/provider.d.ts.map +1 -1
  2. package/lib/eth/provider.js +3 -3
  3. package/lib/eth/provider.js.map +1 -1
  4. package/lib/store/codegen.d.ts +0 -2
  5. package/lib/store/codegen.d.ts.map +1 -1
  6. package/lib/store/codegen.js +147 -158
  7. package/lib/store/codegen.js.map +1 -1
  8. package/lib/store/convert.d.ts +32 -0
  9. package/lib/store/convert.d.ts.map +1 -0
  10. package/lib/store/convert.js +293 -0
  11. package/lib/store/convert.js.map +1 -0
  12. package/lib/store/convert.test.d.ts +2 -0
  13. package/lib/store/convert.test.d.ts.map +1 -0
  14. package/lib/store/convert.test.js.map +1 -0
  15. package/lib/store/decorators.d.ts +24 -7
  16. package/lib/store/decorators.d.ts.map +1 -1
  17. package/lib/store/decorators.js +160 -16
  18. package/lib/store/decorators.js.map +1 -1
  19. package/lib/store/index.d.ts +1 -1
  20. package/lib/store/index.d.ts.map +1 -1
  21. package/lib/store/index.js +1 -1
  22. package/lib/store/index.js.map +1 -1
  23. package/lib/store/schema.d.ts.map +1 -1
  24. package/lib/store/schema.js +39 -1
  25. package/lib/store/schema.js.map +1 -1
  26. package/lib/store/store.d.ts +23 -4
  27. package/lib/store/store.d.ts.map +1 -1
  28. package/lib/store/store.js +119 -59
  29. package/lib/store/store.js.map +1 -1
  30. package/lib/store/types.d.ts +22 -5
  31. package/lib/store/types.d.ts.map +1 -1
  32. package/lib/store/types.js +14 -1
  33. package/lib/store/types.js.map +1 -1
  34. package/package.json +4 -3
  35. package/src/eth/provider.ts +8 -3
  36. package/src/store/codegen.ts +183 -185
  37. package/src/store/convert.ts +321 -0
  38. package/src/store/decorators.ts +185 -16
  39. package/src/store/index.ts +1 -1
  40. package/src/store/schema.ts +41 -1
  41. package/src/store/store.ts +157 -56
  42. package/src/store/types.ts +25 -6
  43. package/lib/store/entity.d.ts +0 -17
  44. package/lib/store/entity.d.ts.map +0 -1
  45. package/lib/store/entity.js +0 -61
  46. package/lib/store/entity.js.map +0 -1
  47. package/src/store/entity.ts +0 -71
@@ -1,40 +1,68 @@
1
- import { Entity, EntityClass } from './entity.js'
2
1
  import { StoreContext } from './context.js'
3
2
  import { DatabaseSchema } from '../core/index.js'
4
3
  import { BigDecimal } from '@sentio/bigdecimal'
4
+ import { Bytes, Float, ID, Int, Timestamp } from './types.js'
5
+ import type { Entity as EntityStruct, RichValue } from '@sentio/protos'
6
+ import { DBRequest_DBOperator, DBResponse } from '@sentio/protos'
7
+ import { toBigInteger } from './convert.js'
8
+ import { PluginManager } from '@sentio/runtime'
9
+
10
+ type Value = ID | string | Int | Float | boolean | Timestamp | Bytes | BigDecimal | bigint
11
+
12
+ interface Entity {
13
+ id: ID
14
+ }
15
+
16
+ export interface EntityClass<T> {
17
+ new (data: Partial<T>): T
18
+ }
5
19
 
6
20
  export class Store {
7
21
  constructor(private readonly context: StoreContext) {}
8
22
 
9
- async get<T extends Entity>(entity: EntityClass<T> | string, id: string): Promise<T | undefined> {
23
+ async get<T extends Entity>(entity: EntityClass<T> | string, id: ID): Promise<T | undefined> {
10
24
  const promise = this.context.sendRequest({
11
25
  get: {
12
26
  entity: typeof entity == 'string' ? entity : entity.prototype.entityName,
13
- id
27
+ id: id.toString()
14
28
  }
15
29
  })
16
30
 
17
- const data = (await promise) as any
18
- if (data?.['id'] != null) {
19
- return this.newEntity(entity, data)
31
+ const data = (await promise) as DBResponse
32
+ if (data.entityList?.entities[0]) {
33
+ const entityData = data.entityList?.entities[0]
34
+ return this.newEntity(entity, entityData)
20
35
  }
36
+
21
37
  return undefined
22
38
  }
23
39
 
24
- async delete(entity: EntityClass<any>, id: string | string[]): Promise<void> {
25
- const toBeDeleted = []
26
- if (Array.isArray(id)) {
27
- for (const i of id) {
28
- toBeDeleted.push({ entity: entity.prototype.entityName, id: i })
40
+ async delete<T extends Entity>(entity: EntityClass<T> | T | T[], id?: string | string[]): Promise<void> {
41
+ const request = {
42
+ entity: [] as string[],
43
+ id: [] as string[]
44
+ }
45
+ if (id) {
46
+ if (Array.isArray(id)) {
47
+ for (const i of id) {
48
+ const items = (entity as any).prototype.entityName
49
+ request.entity.push(items)
50
+ request.id.push(i.toString())
51
+ }
52
+ } else {
53
+ request.entity.push((entity as any).prototype.entityName)
54
+ request.id.push(id)
29
55
  }
30
56
  } else {
31
- toBeDeleted.push({ entity: entity.prototype.entityName, id })
57
+ const entities = Array.isArray(entity) ? entity : [entity]
58
+ for (const e of entities) {
59
+ request.entity.push(e.constructor.prototype.entityName)
60
+ request.id.push((e as Entity).id.toString())
61
+ }
32
62
  }
63
+
33
64
  await this.context.sendRequest({
34
- delete: {
35
- entity: toBeDeleted.map((e) => e.entity) as string[],
36
- id: toBeDeleted.map((e) => e.id) as string[]
37
- }
65
+ delete: request
38
66
  })
39
67
  }
40
68
 
@@ -43,65 +71,138 @@ export class Store {
43
71
  const promise = this.context.sendRequest({
44
72
  upsert: {
45
73
  entity: entities.map((e) => e.constructor.prototype.entityName),
46
- data: entities.map((e) => serialize(e.data)),
47
- id: entities.map((e) => e.id)
74
+ // data: entities.map((e) => serialize(e.data)),
75
+ id: entities.map((e) => e.id.toString()),
76
+ entityData: entities.map((e: any) => e._data)
48
77
  }
49
78
  })
50
79
 
51
80
  await promise
52
81
  }
53
82
 
54
- async list<T extends Entity>(entity: EntityClass<T>, limit?: number, offset?: number): Promise<T[]> {
55
- const promise = this.context.sendRequest({
56
- list: {
57
- entity: entity.prototype.entityName,
58
- limit,
59
- offset
60
- }
61
- })
83
+ async *list<T extends Entity>(entity: EntityClass<T>, filters?: ListFilter<T>[]) {
84
+ let cursor: string | undefined = undefined
62
85
 
63
- const list = (await promise) as any[]
64
- return list.map((data) => {
65
- return this.newEntity(entity, data)
66
- })
86
+ while (true) {
87
+ const promise = this.context.sendRequest({
88
+ list: {
89
+ entity: entity.prototype.entityName,
90
+ cursor,
91
+ filters:
92
+ filters?.map((f) => ({
93
+ field: f.field as string,
94
+ op: ops[f.op],
95
+ value: { values: Array.isArray(f.value) ? f.value.map((v) => serialize(v)) : [serialize(f.value)] }
96
+ })) || []
97
+ }
98
+ })
99
+ const response = (await promise) as DBResponse
100
+ for (const data of response.entityList?.entities || []) {
101
+ yield this.newEntity(entity, data)
102
+ }
103
+ if (!response.nextCursor) {
104
+ break
105
+ }
106
+ cursor = response.nextCursor
107
+ }
67
108
  }
68
109
 
69
- private newEntity<T extends Entity>(entity: EntityClass<T> | string, data: any) {
110
+ private newEntity<T extends Entity>(entity: EntityClass<T> | string, data: EntityStruct) {
70
111
  if (typeof entity == 'string') {
71
- const en = DatabaseSchema.findEntity(entity)
112
+ let en = DatabaseSchema.findEntity(entity)
72
113
  if (!en) {
73
114
  // it is an interface
74
- return new Entity(data) as T
115
+ en = DatabaseSchema.findEntity(data.entity)
116
+ if (!en) {
117
+ throw new Error(`Entity ${entity} not found`)
118
+ }
75
119
  }
76
120
  entity = en
77
121
  }
78
122
 
79
- return new (entity as EntityClass<T>)(data)
123
+ const res = new (entity as EntityClass<T>)({}) as T
124
+ ;(res as any)._data = data.data
125
+ return res
80
126
  }
81
127
  }
82
128
 
83
- function serialize(data: Record<string, any>) {
84
- const ret: Record<string, any> = {}
85
- for (const [k, v] of Object.entries(data)) {
86
- if (v instanceof Entity) {
87
- ret[k] = v.id
88
- } else if (Array.isArray(v) && v[0] instanceof Entity) {
89
- ret[k] = v.map((e) => e.id)
90
- } else if (typeof v === 'bigint') {
91
- ret[k] = v.toString()
92
- } else if (typeof v === 'object') {
93
- if (v instanceof Date) {
94
- ret[k] = v.toISOString()
95
- } else if (v instanceof Uint8Array) {
96
- ret[k] = Buffer.from(v).toString('hex')
97
- } else if (v instanceof BigDecimal) {
98
- ret[k] = v.toString()
99
- } else {
100
- ret[k] = serialize(v)
101
- }
102
- } else {
103
- ret[k] = v
129
+ export type Operators = '=' | '!=' | '<' | '<=' | '>' | '>=' | 'in' | 'not in'
130
+
131
+ export interface ListFilter<T extends Entity> {
132
+ field: keyof T
133
+ op: Operators
134
+ value: Value | Value[] | null
135
+ }
136
+
137
+ export interface ListOptions<T extends Entity> {
138
+ cursor: string
139
+ }
140
+
141
+ const ops: Record<Operators, DBRequest_DBOperator> = {
142
+ '=': DBRequest_DBOperator.EQ,
143
+ '!=': DBRequest_DBOperator.NE,
144
+ '<': DBRequest_DBOperator.LT,
145
+ '<=': DBRequest_DBOperator.LE,
146
+ '>': DBRequest_DBOperator.GT,
147
+ '>=': DBRequest_DBOperator.GE,
148
+ in: DBRequest_DBOperator.IN,
149
+ 'not in': DBRequest_DBOperator.NOT_IN
150
+ }
151
+
152
+ function serialize(v: any): RichValue {
153
+ if (v == null) {
154
+ return { nullValue: 0 }
155
+ }
156
+ if (typeof v == 'boolean') {
157
+ return { boolValue: v }
158
+ }
159
+ if (typeof v == 'string') {
160
+ return { stringValue: v }
161
+ }
162
+
163
+ if (typeof v == 'number') {
164
+ return { floatValue: v }
165
+ }
166
+ if (typeof v == 'bigint') {
167
+ return {
168
+ bigintValue: toBigInteger(v)
169
+ }
170
+ }
171
+
172
+ if (v instanceof BigDecimal) {
173
+ return serializeBigDecimal(v)
174
+ }
175
+
176
+ if (v instanceof Date) {
177
+ return {
178
+ timestampValue: v
104
179
  }
105
180
  }
106
- return ret
181
+
182
+ if (v instanceof Uint8Array) {
183
+ return { bytesValue: v }
184
+ }
185
+
186
+ if (Array.isArray(v)) {
187
+ return {
188
+ listValue: { values: v.map((v) => serialize(v)) }
189
+ }
190
+ }
191
+ return {
192
+ nullValue: 0
193
+ }
194
+ }
195
+
196
+ function serializeBigDecimal(v: BigDecimal): RichValue {
197
+ return {
198
+ bigdecimalValue: undefined
199
+ }
200
+ }
201
+
202
+ export function getStore() {
203
+ const dbContext = PluginManager.INSTANCE.dbContextLocalStorage.getStore()
204
+ if (dbContext) {
205
+ return new Store(dbContext)
206
+ }
207
+ return undefined
107
208
  }
@@ -1,10 +1,29 @@
1
- export type { BigDecimal } from '@sentio/bigdecimal'
2
-
3
- export type ID = string
1
+ export type ID = (string | Uint8Array) & { __id__?: void }
4
2
  export type String = string
5
- export type Int = number
3
+ export type Int = number & { __int__?: void }
6
4
  export type Float = number
7
5
  export type Boolean = boolean
8
- export type DateTime = Date
9
- export type Json = any
6
+ export type Timestamp = Date
10
7
  export type Bytes = Uint8Array
8
+ export type BigInt = bigint
9
+
10
+ export class Struct<T = unknown, S = unknown> {
11
+ readonly TYPE!: T
12
+ constructor(readonly schema: S) {}
13
+ }
14
+ export type Infer<T extends Struct<any>> = T['TYPE']
15
+ export type ObjectSchema = Record<string, Struct<any, any>>
16
+
17
+ export function object<S extends ObjectSchema>(schema: S): Struct<ObjectType<S>, S> {
18
+ return new Struct(schema ?? null)
19
+ }
20
+
21
+ export type Simplify<T> = T extends any[] | Date ? T : { [K in keyof T]: T[K] } & NonNullable<unknown>
22
+
23
+ export type ObjectType<S extends ObjectSchema> = Simplify<{ [K in keyof S]: Infer<S[K]> }>
24
+
25
+ const StringStruct = new Struct<string, null>(null)
26
+
27
+ const UU = object({
28
+ test: StringStruct
29
+ })
@@ -1,17 +0,0 @@
1
- import { ID } from './types.js';
2
- export interface EntityClass<T extends Entity> {
3
- new (data: any): T;
4
- }
5
- export declare class Entity {
6
- get id(): ID;
7
- data: Record<string, any>;
8
- constructor(data: any);
9
- private getIdFromEntity;
10
- private getStore;
11
- get<T>(field: string): T;
12
- set<T>(field: string, value: T | T[] | ID | ID[]): void;
13
- protected getFieldObject<T extends Entity>(entity: EntityClass<T> | string, field: string): Promise<T | undefined>;
14
- protected getFieldObjectArray<T extends Entity>(entity: EntityClass<T>, field: string): Promise<T[]>;
15
- toString(): string;
16
- }
17
- //# sourceMappingURL=entity.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../src/store/entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAA;AAI/B,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,MAAM;IAC3C,KAAK,IAAI,EAAE,GAAG,GAAG,CAAC,CAAA;CACnB;AAED,qBAAa,MAAM;IACjB,IAAI,EAAE,IAAI,EAAE,CAEX;IAED,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAK;gBAClB,IAAI,EAAE,GAAG;IAUrB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,QAAQ;IAQhB,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC;IAIxB,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,IAAI;IASvD,SAAS,CAAC,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAKlH,SAAS,CAAC,mBAAmB,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAMpG,QAAQ,IAAI,MAAM;CAKnB"}
@@ -1,61 +0,0 @@
1
- import { PluginManager } from '@sentio/runtime';
2
- import { Store } from './store.js';
3
- export class Entity {
4
- get id() {
5
- return this.get('id');
6
- }
7
- data = {};
8
- constructor(data) {
9
- Object.entries(data).forEach(([key, value]) => {
10
- if (Array.isArray(value)) {
11
- this.data[key] = value.map((v) => this.getIdFromEntity(v));
12
- }
13
- else {
14
- this.data[key] = this.getIdFromEntity(value);
15
- }
16
- });
17
- }
18
- getIdFromEntity(entity) {
19
- if (entity instanceof Entity) {
20
- return entity.id;
21
- }
22
- else if (typeof entity === 'object' && entity.id) {
23
- return entity.id;
24
- }
25
- return entity;
26
- }
27
- getStore() {
28
- const dbContext = PluginManager.INSTANCE.dbContextLocalStorage.getStore();
29
- if (dbContext) {
30
- return new Store(dbContext);
31
- }
32
- return undefined;
33
- }
34
- get(field) {
35
- return this.data[field];
36
- }
37
- set(field, value) {
38
- if (Array.isArray(value) && value instanceof Entity) {
39
- this.data[field] = value.map((v) => v.id);
40
- }
41
- else if (value instanceof Entity) {
42
- this.data[field] = value.id;
43
- }
44
- this.data[field] = value;
45
- }
46
- getFieldObject(entity, field) {
47
- const id = this.data[field];
48
- return id ? this.getStore()?.get(entity, id) : Promise.resolve(undefined);
49
- }
50
- getFieldObjectArray(entity, field) {
51
- const ids = this.data[field];
52
- const promises = ids.map((id) => this.getStore()?.get(entity, id));
53
- return Promise.all(promises);
54
- }
55
- toString() {
56
- const entityName = this.constructor.prototype.entityName;
57
- const id = this.id;
58
- return `${entityName}#${id} ${JSON.stringify(this.data)}`;
59
- }
60
- }
61
- //# sourceMappingURL=entity.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/store/entity.ts"],"names":[],"mappings":"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"}
@@ -1,71 +0,0 @@
1
- import { ID } from './types.js'
2
- import { PluginManager } from '@sentio/runtime'
3
- import { Store } from './store.js'
4
-
5
- export interface EntityClass<T extends Entity> {
6
- new (data: any): T
7
- }
8
-
9
- export class Entity {
10
- get id(): ID {
11
- return this.get('id')
12
- }
13
-
14
- data: Record<string, any> = {}
15
- constructor(data: any) {
16
- Object.entries(data).forEach(([key, value]) => {
17
- if (Array.isArray(value)) {
18
- this.data[key] = value.map((v) => this.getIdFromEntity(v))
19
- } else {
20
- this.data[key] = this.getIdFromEntity(value)
21
- }
22
- })
23
- }
24
-
25
- private getIdFromEntity(entity: any): any {
26
- if (entity instanceof Entity) {
27
- return entity.id
28
- } else if (typeof entity === 'object' && entity.id) {
29
- return entity.id
30
- }
31
- return entity
32
- }
33
-
34
- private getStore() {
35
- const dbContext = PluginManager.INSTANCE.dbContextLocalStorage.getStore()
36
- if (dbContext) {
37
- return new Store(dbContext)
38
- }
39
- return undefined
40
- }
41
-
42
- get<T>(field: string): T {
43
- return this.data[field]
44
- }
45
-
46
- set<T>(field: string, value: T | T[] | ID | ID[]): void {
47
- if (Array.isArray(value) && value instanceof Entity) {
48
- this.data[field] = value.map((v) => (v as Entity).id)
49
- } else if (value instanceof Entity) {
50
- this.data[field] = (value as Entity).id
51
- }
52
- this.data[field] = value
53
- }
54
-
55
- protected getFieldObject<T extends Entity>(entity: EntityClass<T> | string, field: string): Promise<T | undefined> {
56
- const id = this.data[field]
57
- return id ? (this.getStore()?.get(entity, id) as Promise<T>) : Promise.resolve(undefined)
58
- }
59
-
60
- protected getFieldObjectArray<T extends Entity>(entity: EntityClass<T>, field: string): Promise<T[]> {
61
- const ids = this.data[field]
62
- const promises = ids.map((id: string) => this.getStore()?.get(entity, id))
63
- return Promise.all(promises) as Promise<T[]>
64
- }
65
-
66
- toString(): string {
67
- const entityName = this.constructor.prototype.entityName
68
- const id = this.id
69
- return `${entityName}#${id} ${JSON.stringify(this.data)}`
70
- }
71
- }