@xyo-network/payload-builder 3.6.0-rc.1 → 3.6.0-rc.11
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/browser/Builder.d.ts +10 -4
- package/dist/browser/Builder.d.ts.map +1 -1
- package/dist/browser/BuilderBase.d.ts +20 -17
- package/dist/browser/BuilderBase.d.ts.map +1 -1
- package/dist/browser/Options.d.ts +1 -4
- package/dist/browser/Options.d.ts.map +1 -1
- package/dist/browser/index.mjs +67 -26
- package/dist/browser/index.mjs.map +1 -1
- package/dist/neutral/Builder.d.ts +10 -4
- package/dist/neutral/Builder.d.ts.map +1 -1
- package/dist/neutral/BuilderBase.d.ts +20 -17
- package/dist/neutral/BuilderBase.d.ts.map +1 -1
- package/dist/neutral/Options.d.ts +1 -4
- package/dist/neutral/Options.d.ts.map +1 -1
- package/dist/neutral/index.mjs +67 -26
- package/dist/neutral/index.mjs.map +1 -1
- package/dist/node/Builder.d.ts +10 -4
- package/dist/node/Builder.d.ts.map +1 -1
- package/dist/node/BuilderBase.d.ts +20 -17
- package/dist/node/BuilderBase.d.ts.map +1 -1
- package/dist/node/Options.d.ts +1 -4
- package/dist/node/Options.d.ts.map +1 -1
- package/dist/node/index.mjs +67 -26
- package/dist/node/index.mjs.map +1 -1
- package/package.json +11 -11
- package/src/Builder.ts +66 -5
- package/src/BuilderBase.ts +59 -40
- package/src/Options.ts +1 -4
package/src/Builder.ts
CHANGED
|
@@ -1,15 +1,66 @@
|
|
|
1
1
|
import type { Hash } from '@xylabs/hex'
|
|
2
2
|
import type { AnyObject } from '@xylabs/object'
|
|
3
3
|
import { ObjectHasher } from '@xyo-network/hash'
|
|
4
|
-
import
|
|
4
|
+
import {
|
|
5
|
+
type Payload,
|
|
6
|
+
SequenceParser,
|
|
7
|
+
type WithHashMeta,
|
|
8
|
+
type WithoutStorageMeta,
|
|
9
|
+
type WithStorageMeta,
|
|
10
|
+
} from '@xyo-network/payload-model'
|
|
5
11
|
|
|
6
12
|
import { PayloadBuilderBase } from './BuilderBase.ts'
|
|
7
|
-
import type { PayloadBuilderOptions } from './Options.ts'
|
|
8
13
|
|
|
9
14
|
export class PayloadBuilder<
|
|
10
15
|
T extends Payload = Payload<AnyObject>,
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
> extends PayloadBuilderBase<T> {
|
|
17
|
+
static async addHashMeta<T extends Payload>(payload: T): Promise<WithHashMeta<T>>
|
|
18
|
+
static async addHashMeta<T extends Payload>(payloads: T[]): Promise<WithHashMeta<T>[]>
|
|
19
|
+
static async addHashMeta<T extends Payload>(payloads: T | T[]): Promise<WithHashMeta<T>[] | WithHashMeta<T>> {
|
|
20
|
+
if (Array.isArray(payloads)) {
|
|
21
|
+
return await Promise.all(
|
|
22
|
+
payloads.map(async (payload) => {
|
|
23
|
+
return await this.addHashMeta(payload)
|
|
24
|
+
}),
|
|
25
|
+
)
|
|
26
|
+
} else {
|
|
27
|
+
const _hash = await PayloadBuilder.hash(payloads)
|
|
28
|
+
const _dataHash = await PayloadBuilder.dataHash(payloads)
|
|
29
|
+
return {
|
|
30
|
+
...payloads,
|
|
31
|
+
_dataHash,
|
|
32
|
+
_hash,
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static async addSequencedStorageMeta<T extends Payload = Payload>(payload: T): Promise<WithStorageMeta<T>> {
|
|
38
|
+
const withHashMeta = await this.addHashMeta(payload)
|
|
39
|
+
const _sequence = SequenceParser.from(Date.now(), withHashMeta._hash).localSequence
|
|
40
|
+
return {
|
|
41
|
+
...withHashMeta,
|
|
42
|
+
_sequence,
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static async addStorageMeta<T extends Payload>(payload: T): Promise<WithStorageMeta<T>>
|
|
47
|
+
static async addStorageMeta<T extends Payload>(payloads: T[]): Promise<WithStorageMeta<T>[]>
|
|
48
|
+
static async addStorageMeta<T extends Payload>(payloads: T | T[]): Promise<WithStorageMeta<T>[] | WithStorageMeta<T>> {
|
|
49
|
+
return Array.isArray(payloads)
|
|
50
|
+
? await (async () => {
|
|
51
|
+
return await Promise.all(payloads.map(async payload => await this.addSequencedStorageMeta(
|
|
52
|
+
payload,
|
|
53
|
+
)))
|
|
54
|
+
})()
|
|
55
|
+
: this.addSequencedStorageMeta(
|
|
56
|
+
payloads,
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static compareStorageMeta(a: WithStorageMeta<Payload>, b: WithStorageMeta<Payload>) {
|
|
61
|
+
return a._sequence > b._sequence ? 1 : a._sequence < b._sequence ? -1 : 0
|
|
62
|
+
}
|
|
63
|
+
|
|
13
64
|
static async dataHash<T extends Payload>(payload: T): Promise<Hash> {
|
|
14
65
|
return await ObjectHasher.hash(this.omitMeta(payload))
|
|
15
66
|
}
|
|
@@ -72,7 +123,7 @@ export class PayloadBuilder<
|
|
|
72
123
|
|
|
73
124
|
static hashableFields<T extends Payload>(
|
|
74
125
|
payload: T,
|
|
75
|
-
): T {
|
|
126
|
+
): WithoutStorageMeta<T> {
|
|
76
127
|
return this.omitStorageMeta(payload)
|
|
77
128
|
}
|
|
78
129
|
|
|
@@ -82,6 +133,15 @@ export class PayloadBuilder<
|
|
|
82
133
|
return await ObjectHasher.hashes(payloads)
|
|
83
134
|
}
|
|
84
135
|
|
|
136
|
+
static sortByStorageMeta<T extends Payload>(payloads: WithStorageMeta<T>[], direction: -1 | 1 = 1) {
|
|
137
|
+
return payloads.sort((a, b) =>
|
|
138
|
+
a._sequence < b._sequence
|
|
139
|
+
? -direction
|
|
140
|
+
: a._sequence > b._sequence
|
|
141
|
+
? direction
|
|
142
|
+
: 0)
|
|
143
|
+
}
|
|
144
|
+
|
|
85
145
|
static async toAllHashMap<T extends Payload>(payloads: T[]): Promise<Record<Hash, T>> {
|
|
86
146
|
const result: Record<Hash, T> = {}
|
|
87
147
|
for (const pair of await this.hashPairs(payloads)) {
|
|
@@ -117,6 +177,7 @@ export class PayloadBuilder<
|
|
|
117
177
|
return {
|
|
118
178
|
schema: this._schema,
|
|
119
179
|
...this._fields,
|
|
180
|
+
...this._meta,
|
|
120
181
|
} as T
|
|
121
182
|
}
|
|
122
183
|
}
|
package/src/BuilderBase.ts
CHANGED
|
@@ -1,82 +1,101 @@
|
|
|
1
1
|
import { assertEx } from '@xylabs/assert'
|
|
2
|
-
import type { AnyObject } from '@xylabs/object'
|
|
2
|
+
import type { AnyObject, EmptyObject } from '@xylabs/object'
|
|
3
3
|
import {
|
|
4
|
-
isJsonObject,
|
|
4
|
+
isJsonObject, omitByPrefix, pickByPrefix, toJson,
|
|
5
5
|
} from '@xylabs/object'
|
|
6
6
|
import type { Promisable } from '@xylabs/promise'
|
|
7
7
|
import { removeEmptyFields } from '@xyo-network/hash'
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
Payload, Schema,
|
|
10
|
+
WithOnlyClientMeta,
|
|
11
|
+
WithOptionalSchema,
|
|
12
|
+
WithoutClientMeta,
|
|
13
|
+
WithoutMeta,
|
|
14
|
+
WithoutPrivateStorageMeta,
|
|
15
|
+
WithoutSchema,
|
|
16
|
+
WithoutStorageMeta,
|
|
17
|
+
} from '@xyo-network/payload-model'
|
|
9
18
|
|
|
10
|
-
import { PayloadBuilder } from './Builder.ts'
|
|
11
19
|
import type { PayloadBuilderOptions } from './Options.ts'
|
|
12
20
|
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
export type WithoutSchema<T extends WithOptionalSchema<Payload>> = Omit<T, 'schema'>
|
|
16
|
-
|
|
17
|
-
export const removeMetaAndSchema = <T extends Payload>(payload: Partial<WithOptionalSchema<T>>): WithoutSchema<T> => {
|
|
18
|
-
const { ...result } = PayloadBuilder.omitMeta(payload as T) as WithOptionalSchema<T>
|
|
21
|
+
export const omitSchema = <T extends WithOptionalSchema>(payload: T): WithoutSchema<T> => {
|
|
22
|
+
const result = structuredClone(payload)
|
|
19
23
|
delete result.schema
|
|
20
|
-
return result
|
|
24
|
+
return result
|
|
21
25
|
}
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export class PayloadBuilderBase<T extends Payload = Payload<AnyObject>, O extends PayloadBuilderOptions<T> = PayloadBuilderOptions<T>> {
|
|
29
|
-
protected _fields?: Partial<WithoutSchema<T>>
|
|
27
|
+
export class PayloadBuilderBase<T extends Payload = Payload<AnyObject>> {
|
|
28
|
+
protected _fields?: WithoutMeta<WithoutSchema<T>>
|
|
29
|
+
protected _meta?: WithOnlyClientMeta<T>
|
|
30
30
|
protected _schema: Schema
|
|
31
31
|
|
|
32
|
-
constructor(readonly options:
|
|
33
|
-
const { schema
|
|
32
|
+
constructor(readonly options: PayloadBuilderOptions) {
|
|
33
|
+
const { schema } = options
|
|
34
34
|
this._schema = schema
|
|
35
|
-
this._fields = removeMetaAndSchema(removeEmptyFields(structuredClone(fields ?? {})))
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
static dataHashableFields<T extends Payload>(
|
|
39
38
|
schema: Schema,
|
|
40
39
|
payload: WithoutSchema<T>,
|
|
41
40
|
|
|
42
|
-
): Promisable<
|
|
41
|
+
): Promisable<WithoutMeta<T>> {
|
|
43
42
|
const cleanFields = removeEmptyFields({ ...payload, schema })
|
|
44
43
|
assertEx(
|
|
45
44
|
cleanFields === undefined || isJsonObject(cleanFields),
|
|
46
45
|
() => `Fields must be JsonObject: ${JSON.stringify(toJson(cleanFields), null, 2)}`,
|
|
47
46
|
)
|
|
48
|
-
return this.omitMeta(cleanFields) as T
|
|
47
|
+
return this.omitMeta(cleanFields) as WithoutMeta<T>
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
static omitClientMeta<T extends
|
|
52
|
-
|
|
50
|
+
static omitClientMeta<T extends EmptyObject>(payload: T, maxDepth?: number): WithoutClientMeta<T>
|
|
51
|
+
static omitClientMeta<T extends EmptyObject>(payloads: T[], maxDepth?: number): WithoutClientMeta<T>[]
|
|
52
|
+
static omitClientMeta<T extends EmptyObject>(payloads: T | T[], maxDepth = 100): WithoutClientMeta<T> | WithoutClientMeta<T>[] {
|
|
53
|
+
return Array.isArray(payloads)
|
|
54
|
+
? payloads.map(payload => this.omitClientMeta(payload, maxDepth))
|
|
55
|
+
: omitByPrefix(payloads, '$', maxDepth)
|
|
53
56
|
}
|
|
54
57
|
|
|
55
|
-
static omitMeta<T extends
|
|
56
|
-
|
|
58
|
+
static omitMeta<T extends EmptyObject>(payload: T, maxDepth?: number): WithoutMeta<T>
|
|
59
|
+
static omitMeta<T extends EmptyObject>(payloads: T[], maxDepth?: number): WithoutMeta<T>[]
|
|
60
|
+
static omitMeta<T extends EmptyObject>(payloads: T | T[], maxDepth = 100): WithoutMeta<T> | WithoutMeta<T>[] {
|
|
61
|
+
return Array.isArray(payloads)
|
|
62
|
+
? payloads.map(payload => this.omitMeta(payload, maxDepth))
|
|
63
|
+
: this.omitStorageMeta(this.omitClientMeta(payloads, maxDepth), maxDepth) as unknown as WithoutMeta<T>
|
|
57
64
|
}
|
|
58
65
|
|
|
59
|
-
static
|
|
60
|
-
|
|
66
|
+
static omitPrivateStorageMeta<T extends EmptyObject>(payload: T, maxDepth?: number): WithoutPrivateStorageMeta<T>
|
|
67
|
+
static omitPrivateStorageMeta<T extends EmptyObject>(payloads: T[], maxDepth?: number): WithoutPrivateStorageMeta<T>[]
|
|
68
|
+
static omitPrivateStorageMeta<T extends EmptyObject>(payloads: T | T[], maxDepth = 100): WithoutPrivateStorageMeta<T> | WithoutPrivateStorageMeta<T>[] {
|
|
69
|
+
return Array.isArray(payloads)
|
|
70
|
+
? payloads.map(payload => this.omitPrivateStorageMeta(payload, maxDepth))
|
|
71
|
+
: omitByPrefix(payloads, '__', maxDepth)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static omitStorageMeta<T extends EmptyObject>(payload: T, maxDepth?: number): WithoutStorageMeta<T>
|
|
75
|
+
static omitStorageMeta<T extends EmptyObject>(payloads: T[], maxDepth?: number): WithoutStorageMeta<T>[]
|
|
76
|
+
static omitStorageMeta<T extends EmptyObject>(payloads: T | T[], maxDepth = 100): WithoutStorageMeta<T> | WithoutStorageMeta<T>[] {
|
|
77
|
+
return Array.isArray(payloads)
|
|
78
|
+
? payloads.map(payload => this.omitStorageMeta(payload, maxDepth))
|
|
79
|
+
: omitByPrefix(payloads, '_', maxDepth)
|
|
61
80
|
}
|
|
62
81
|
|
|
63
82
|
async dataHashableFields() {
|
|
64
83
|
return await PayloadBuilderBase.dataHashableFields(
|
|
65
84
|
assertEx(this._schema, () => 'Payload: Missing Schema'),
|
|
66
|
-
//
|
|
67
|
-
this._fields as T
|
|
85
|
+
// TODO: Add verification that required fields are present
|
|
86
|
+
this._fields as WithoutSchema<T>,
|
|
68
87
|
)
|
|
69
88
|
}
|
|
70
89
|
|
|
71
|
-
fields(fields:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
90
|
+
fields(fields: WithoutMeta<WithoutSchema<T>>) {
|
|
91
|
+
// we need to do the cast here since ts seems to not like nested, yet same, generics
|
|
92
|
+
this._fields = omitSchema(PayloadBuilderBase.omitMeta(removeEmptyFields(structuredClone(fields)))) as unknown as WithoutMeta<WithoutSchema<T>>
|
|
93
|
+
return this
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
meta(meta: WithOnlyClientMeta<T>) {
|
|
97
|
+
// we need to do the cast here since ts seems to not like nested, yet same, generics
|
|
98
|
+
this._meta = pickByPrefix(meta, '$') as WithOnlyClientMeta<T>
|
|
80
99
|
return this
|
|
81
100
|
}
|
|
82
101
|
|
package/src/Options.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import type { Logger } from '@xylabs/logger'
|
|
2
|
-
import type { JsonObject } from '@xylabs/object'
|
|
3
2
|
import type { Schema } from '@xyo-network/payload-model'
|
|
4
3
|
|
|
5
|
-
export interface PayloadBuilderOptions
|
|
6
|
-
readonly fields?: Partial<T>
|
|
4
|
+
export interface PayloadBuilderOptions {
|
|
7
5
|
readonly logger?: Logger
|
|
8
|
-
readonly meta?: JsonObject
|
|
9
6
|
readonly schema: Schema
|
|
10
7
|
}
|