@whitewall/blip-sdk 0.0.138 → 0.0.140

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 (36) hide show
  1. package/dist/cjs/namespaces/account.js +85 -0
  2. package/dist/cjs/namespaces/account.js.map +1 -1
  3. package/dist/cjs/namespaces/namespace.js +78 -38
  4. package/dist/cjs/namespaces/namespace.js.map +1 -1
  5. package/dist/cjs/namespaces/portal.js +4 -1
  6. package/dist/cjs/namespaces/portal.js.map +1 -1
  7. package/dist/cjs/sender/enveloperesolver.js +3 -3
  8. package/dist/cjs/sender/enveloperesolver.js.map +1 -1
  9. package/dist/cjs/sender/throttler.js +51 -21
  10. package/dist/cjs/sender/throttler.js.map +1 -1
  11. package/dist/esm/namespaces/account.js +85 -0
  12. package/dist/esm/namespaces/account.js.map +1 -1
  13. package/dist/esm/namespaces/namespace.js +78 -38
  14. package/dist/esm/namespaces/namespace.js.map +1 -1
  15. package/dist/esm/namespaces/portal.js +4 -1
  16. package/dist/esm/namespaces/portal.js.map +1 -1
  17. package/dist/esm/sender/enveloperesolver.js +3 -3
  18. package/dist/esm/sender/enveloperesolver.js.map +1 -1
  19. package/dist/esm/sender/throttler.js +51 -21
  20. package/dist/esm/sender/throttler.js.map +1 -1
  21. package/dist/types/namespaces/account.d.ts +18 -2
  22. package/dist/types/namespaces/account.d.ts.map +1 -1
  23. package/dist/types/namespaces/namespace.d.ts +25 -5
  24. package/dist/types/namespaces/namespace.d.ts.map +1 -1
  25. package/dist/types/namespaces/portal.d.ts.map +1 -1
  26. package/dist/types/sender/throttler.d.ts +7 -2
  27. package/dist/types/sender/throttler.d.ts.map +1 -1
  28. package/dist/types/types/account.d.ts +10 -0
  29. package/dist/types/types/account.d.ts.map +1 -1
  30. package/package.json +1 -1
  31. package/src/namespaces/account.ts +121 -1
  32. package/src/namespaces/namespace.ts +137 -62
  33. package/src/namespaces/portal.ts +4 -1
  34. package/src/sender/enveloperesolver.ts +3 -3
  35. package/src/sender/throttler.ts +59 -20
  36. package/src/types/account.ts +11 -0
@@ -1,36 +1,75 @@
1
1
  export class EnvelopeThrottler {
2
- private sent = {
2
+ private buckets = {
3
3
  message: {
4
4
  max: 50,
5
- started: 0,
6
- count: 0,
5
+ tokens: 0,
6
+ lastRefill: 0,
7
+ waiting: [] as Array<() => void>,
8
+ timer: null as NodeJS.Timeout | null,
7
9
  },
8
10
  command: {
9
11
  max: 200,
10
- started: 0,
11
- count: 0,
12
+ tokens: 0,
13
+ lastRefill: 0,
14
+ waiting: [] as Array<() => void>,
15
+ timer: null as NodeJS.Timeout | null,
12
16
  },
13
17
  }
14
18
 
15
- public async throttle(type: keyof typeof this.sent): Promise<void> {
16
- const throughput = this.sent[type].max * 0.9
17
- const timeToReset = 1000
19
+ private readonly refillInterval = 1000 // ms
20
+ private readonly throughputFactor = 0.9
21
+ // memo for fast-path (zero allocation)
22
+ private readonly voidPromise = Promise.resolve()
18
23
 
19
- while (true) {
20
- const elapsed = Date.now() - this.sent[type].started
24
+ public throttle(type: keyof typeof this.buckets): Promise<void> {
25
+ const bucket = this.buckets[type]
26
+ this.refillTokens(type)
21
27
 
22
- if (elapsed >= timeToReset) {
23
- this.sent[type].started = Date.now()
24
- this.sent[type].count = 0
28
+ if (bucket.tokens > 0) {
29
+ bucket.tokens--
30
+ return this.voidPromise
31
+ }
32
+
33
+ const { resolve, promise } = Promise.withResolvers<void>()
34
+ bucket.waiting.push(resolve)
35
+
36
+ this.scheduleRefill(type)
37
+
38
+ return promise
39
+ }
40
+
41
+ private refillTokens(type: keyof typeof this.buckets): void {
42
+ const bucket = this.buckets[type]
43
+ const now = Date.now()
44
+ const elapsed = now - bucket.lastRefill
45
+
46
+ if (elapsed >= this.refillInterval) {
47
+ bucket.tokens = Math.floor(bucket.max * this.throughputFactor)
48
+ bucket.lastRefill = now
49
+ }
50
+ }
51
+
52
+ private scheduleRefill(type: keyof typeof this.buckets): void {
53
+ const bucket = this.buckets[type]
54
+ if (bucket.timer) return
55
+
56
+ const delay = Math.max(0, this.refillInterval - (Date.now() - bucket.lastRefill))
57
+
58
+ bucket.timer = setTimeout(() => {
59
+ bucket.timer = null
60
+ this.refillTokens(type)
61
+
62
+ while (bucket.tokens > 0 && bucket.waiting.length > 0) {
63
+ const resolve = bucket.waiting.shift()
64
+ if (resolve) {
65
+ bucket.tokens--
66
+ resolve()
67
+ }
25
68
  }
26
69
 
27
- if (this.sent[type].count < throughput) {
28
- this.sent[type].count++
29
- break
30
- } else {
31
- const wait = timeToReset - elapsed
32
- await new Promise((resolve) => setTimeout(resolve, wait))
70
+ if (bucket.waiting.length > 0) {
71
+ this.scheduleRefill(type)
33
72
  }
34
- }
73
+ }, delay)
35
74
  }
36
75
  }
@@ -82,3 +82,14 @@ export type Comment = {
82
82
  authorIdentity: Identity
83
83
  content: string
84
84
  }
85
+
86
+ export type AccessKey = {
87
+ id: string
88
+ account: Identity
89
+ purpose?: string
90
+ expiration?: string
91
+ requirer: string
92
+ temporary: boolean
93
+ creationDate: string
94
+ key: string
95
+ }