@juzi/file-box 1.7.0

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 (210) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +613 -0
  3. package/dist/cjs/package.json +3 -0
  4. package/dist/cjs/src/config.d.ts +4 -0
  5. package/dist/cjs/src/config.d.ts.map +1 -0
  6. package/dist/cjs/src/config.js +9 -0
  7. package/dist/cjs/src/config.js.map +1 -0
  8. package/dist/cjs/src/file-box.d.ts +209 -0
  9. package/dist/cjs/src/file-box.d.ts.map +1 -0
  10. package/dist/cjs/src/file-box.js +804 -0
  11. package/dist/cjs/src/file-box.js.map +1 -0
  12. package/dist/cjs/src/file-box.spec.d.ts +14 -0
  13. package/dist/cjs/src/file-box.spec.d.ts.map +1 -0
  14. package/dist/cjs/src/file-box.spec.js +393 -0
  15. package/dist/cjs/src/file-box.spec.js.map +1 -0
  16. package/dist/cjs/src/file-box.type.d.ts +103 -0
  17. package/dist/cjs/src/file-box.type.d.ts.map +1 -0
  18. package/dist/cjs/src/file-box.type.js +34 -0
  19. package/dist/cjs/src/file-box.type.js.map +1 -0
  20. package/dist/cjs/src/interface.d.ts +25 -0
  21. package/dist/cjs/src/interface.d.ts.map +1 -0
  22. package/dist/cjs/src/interface.js +3 -0
  23. package/dist/cjs/src/interface.js.map +1 -0
  24. package/dist/cjs/src/interface.spec.d.ts +3 -0
  25. package/dist/cjs/src/interface.spec.d.ts.map +1 -0
  26. package/dist/cjs/src/interface.spec.js +11 -0
  27. package/dist/cjs/src/interface.spec.js.map +1 -0
  28. package/dist/cjs/src/misc.d.ts +17 -0
  29. package/dist/cjs/src/misc.d.ts.map +1 -0
  30. package/dist/cjs/src/misc.js +137 -0
  31. package/dist/cjs/src/misc.js.map +1 -0
  32. package/dist/cjs/src/misc.spec.d.ts +3 -0
  33. package/dist/cjs/src/misc.spec.d.ts.map +1 -0
  34. package/dist/cjs/src/misc.spec.js +51 -0
  35. package/dist/cjs/src/misc.spec.js.map +1 -0
  36. package/dist/cjs/src/mod.d.ts +9 -0
  37. package/dist/cjs/src/mod.d.ts.map +1 -0
  38. package/dist/cjs/src/mod.js +12 -0
  39. package/dist/cjs/src/mod.js.map +1 -0
  40. package/dist/cjs/src/pure-functions/sized-chunk-transformer.d.ts +13 -0
  41. package/dist/cjs/src/pure-functions/sized-chunk-transformer.d.ts.map +1 -0
  42. package/dist/cjs/src/pure-functions/sized-chunk-transformer.js +45 -0
  43. package/dist/cjs/src/pure-functions/sized-chunk-transformer.js.map +1 -0
  44. package/dist/cjs/src/pure-functions/sized-chunk-transformer.spec.d.ts +3 -0
  45. package/dist/cjs/src/pure-functions/sized-chunk-transformer.spec.d.ts.map +1 -0
  46. package/dist/cjs/src/pure-functions/sized-chunk-transformer.spec.js +39 -0
  47. package/dist/cjs/src/pure-functions/sized-chunk-transformer.spec.js.map +1 -0
  48. package/dist/cjs/src/qrcode.d.ts +6 -0
  49. package/dist/cjs/src/qrcode.d.ts.map +1 -0
  50. package/dist/cjs/src/qrcode.js +35 -0
  51. package/dist/cjs/src/qrcode.js.map +1 -0
  52. package/dist/cjs/src/qrcode.spec.d.ts +3 -0
  53. package/dist/cjs/src/qrcode.spec.d.ts.map +1 -0
  54. package/dist/cjs/src/qrcode.spec.js +47 -0
  55. package/dist/cjs/src/qrcode.spec.js.map +1 -0
  56. package/dist/cjs/src/urn-registry/mod.d.ts +3 -0
  57. package/dist/cjs/src/urn-registry/mod.d.ts.map +1 -0
  58. package/dist/cjs/src/urn-registry/mod.js +6 -0
  59. package/dist/cjs/src/urn-registry/mod.js.map +1 -0
  60. package/dist/cjs/src/urn-registry/random-uuid.d.ts +4 -0
  61. package/dist/cjs/src/urn-registry/random-uuid.d.ts.map +1 -0
  62. package/dist/cjs/src/urn-registry/random-uuid.js +30 -0
  63. package/dist/cjs/src/urn-registry/random-uuid.js.map +1 -0
  64. package/dist/cjs/src/urn-registry/uniform-resource-name-registry.d.ts +76 -0
  65. package/dist/cjs/src/urn-registry/uniform-resource-name-registry.d.ts.map +1 -0
  66. package/dist/cjs/src/urn-registry/uniform-resource-name-registry.js +259 -0
  67. package/dist/cjs/src/urn-registry/uniform-resource-name-registry.js.map +1 -0
  68. package/dist/cjs/src/urn-registry/uniform-resource-name-registry.spec.d.ts +3 -0
  69. package/dist/cjs/src/urn-registry/uniform-resource-name-registry.spec.d.ts.map +1 -0
  70. package/dist/cjs/src/urn-registry/uniform-resource-name-registry.spec.js +81 -0
  71. package/dist/cjs/src/urn-registry/uniform-resource-name-registry.spec.js.map +1 -0
  72. package/dist/cjs/src/urn-registry/uuid-to-big-int.d.ts +8 -0
  73. package/dist/cjs/src/urn-registry/uuid-to-big-int.d.ts.map +1 -0
  74. package/dist/cjs/src/urn-registry/uuid-to-big-int.js +16 -0
  75. package/dist/cjs/src/urn-registry/uuid-to-big-int.js.map +1 -0
  76. package/dist/cjs/src/urn-registry/uuid-to-big-int.spec.d.ts +3 -0
  77. package/dist/cjs/src/urn-registry/uuid-to-big-int.spec.d.ts.map +1 -0
  78. package/dist/cjs/src/urn-registry/uuid-to-big-int.spec.js +17 -0
  79. package/dist/cjs/src/urn-registry/uuid-to-big-int.spec.js.map +1 -0
  80. package/dist/cjs/src/version.d.ts +5 -0
  81. package/dist/cjs/src/version.d.ts.map +1 -0
  82. package/dist/cjs/src/version.js +8 -0
  83. package/dist/cjs/src/version.js.map +1 -0
  84. package/dist/cjs/src/version.spec.d.ts +3 -0
  85. package/dist/cjs/src/version.spec.d.ts.map +1 -0
  86. package/dist/cjs/src/version.spec.js +9 -0
  87. package/dist/cjs/src/version.spec.js.map +1 -0
  88. package/dist/cjs/tests/integration.spec.d.ts +3 -0
  89. package/dist/cjs/tests/integration.spec.d.ts.map +1 -0
  90. package/dist/cjs/tests/integration.spec.js +8 -0
  91. package/dist/cjs/tests/integration.spec.js.map +1 -0
  92. package/dist/cjs/tests/network-timeout.spec.d.ts +3 -0
  93. package/dist/cjs/tests/network-timeout.spec.d.ts.map +1 -0
  94. package/dist/cjs/tests/network-timeout.spec.js +121 -0
  95. package/dist/cjs/tests/network-timeout.spec.js.map +1 -0
  96. package/dist/esm/src/config.d.ts +4 -0
  97. package/dist/esm/src/config.d.ts.map +1 -0
  98. package/dist/esm/src/config.js +5 -0
  99. package/dist/esm/src/config.js.map +1 -0
  100. package/dist/esm/src/file-box.d.ts +209 -0
  101. package/dist/esm/src/file-box.d.ts.map +1 -0
  102. package/dist/esm/src/file-box.js +775 -0
  103. package/dist/esm/src/file-box.js.map +1 -0
  104. package/dist/esm/src/file-box.spec.d.ts +14 -0
  105. package/dist/esm/src/file-box.spec.d.ts.map +1 -0
  106. package/dist/esm/src/file-box.spec.js +386 -0
  107. package/dist/esm/src/file-box.spec.js.map +1 -0
  108. package/dist/esm/src/file-box.type.d.ts +103 -0
  109. package/dist/esm/src/file-box.type.d.ts.map +1 -0
  110. package/dist/esm/src/file-box.type.js +31 -0
  111. package/dist/esm/src/file-box.type.js.map +1 -0
  112. package/dist/esm/src/interface.d.ts +25 -0
  113. package/dist/esm/src/interface.d.ts.map +1 -0
  114. package/dist/esm/src/interface.js +2 -0
  115. package/dist/esm/src/interface.js.map +1 -0
  116. package/dist/esm/src/interface.spec.d.ts +3 -0
  117. package/dist/esm/src/interface.spec.d.ts.map +1 -0
  118. package/dist/esm/src/interface.spec.js +9 -0
  119. package/dist/esm/src/interface.spec.js.map +1 -0
  120. package/dist/esm/src/misc.d.ts +17 -0
  121. package/dist/esm/src/misc.d.ts.map +1 -0
  122. package/dist/esm/src/misc.js +126 -0
  123. package/dist/esm/src/misc.js.map +1 -0
  124. package/dist/esm/src/misc.spec.d.ts +3 -0
  125. package/dist/esm/src/misc.spec.d.ts.map +1 -0
  126. package/dist/esm/src/misc.spec.js +49 -0
  127. package/dist/esm/src/misc.spec.js.map +1 -0
  128. package/dist/esm/src/mod.d.ts +9 -0
  129. package/dist/esm/src/mod.d.ts.map +1 -0
  130. package/dist/esm/src/mod.js +6 -0
  131. package/dist/esm/src/mod.js.map +1 -0
  132. package/dist/esm/src/pure-functions/sized-chunk-transformer.d.ts +13 -0
  133. package/dist/esm/src/pure-functions/sized-chunk-transformer.d.ts.map +1 -0
  134. package/dist/esm/src/pure-functions/sized-chunk-transformer.js +39 -0
  135. package/dist/esm/src/pure-functions/sized-chunk-transformer.js.map +1 -0
  136. package/dist/esm/src/pure-functions/sized-chunk-transformer.spec.d.ts +3 -0
  137. package/dist/esm/src/pure-functions/sized-chunk-transformer.spec.d.ts.map +1 -0
  138. package/dist/esm/src/pure-functions/sized-chunk-transformer.spec.js +37 -0
  139. package/dist/esm/src/pure-functions/sized-chunk-transformer.spec.js.map +1 -0
  140. package/dist/esm/src/qrcode.d.ts +6 -0
  141. package/dist/esm/src/qrcode.d.ts.map +1 -0
  142. package/dist/esm/src/qrcode.js +27 -0
  143. package/dist/esm/src/qrcode.js.map +1 -0
  144. package/dist/esm/src/qrcode.spec.d.ts +3 -0
  145. package/dist/esm/src/qrcode.spec.d.ts.map +1 -0
  146. package/dist/esm/src/qrcode.spec.js +45 -0
  147. package/dist/esm/src/qrcode.spec.js.map +1 -0
  148. package/dist/esm/src/urn-registry/mod.d.ts +3 -0
  149. package/dist/esm/src/urn-registry/mod.d.ts.map +1 -0
  150. package/dist/esm/src/urn-registry/mod.js +3 -0
  151. package/dist/esm/src/urn-registry/mod.js.map +1 -0
  152. package/dist/esm/src/urn-registry/random-uuid.d.ts +4 -0
  153. package/dist/esm/src/urn-registry/random-uuid.d.ts.map +1 -0
  154. package/dist/esm/src/urn-registry/random-uuid.js +4 -0
  155. package/dist/esm/src/urn-registry/random-uuid.js.map +1 -0
  156. package/dist/esm/src/urn-registry/uniform-resource-name-registry.d.ts +76 -0
  157. package/dist/esm/src/urn-registry/uniform-resource-name-registry.d.ts.map +1 -0
  158. package/dist/esm/src/urn-registry/uniform-resource-name-registry.js +253 -0
  159. package/dist/esm/src/urn-registry/uniform-resource-name-registry.js.map +1 -0
  160. package/dist/esm/src/urn-registry/uniform-resource-name-registry.spec.d.ts +3 -0
  161. package/dist/esm/src/urn-registry/uniform-resource-name-registry.spec.d.ts.map +1 -0
  162. package/dist/esm/src/urn-registry/uniform-resource-name-registry.spec.js +79 -0
  163. package/dist/esm/src/urn-registry/uniform-resource-name-registry.spec.js.map +1 -0
  164. package/dist/esm/src/urn-registry/uuid-to-big-int.d.ts +8 -0
  165. package/dist/esm/src/urn-registry/uuid-to-big-int.d.ts.map +1 -0
  166. package/dist/esm/src/urn-registry/uuid-to-big-int.js +13 -0
  167. package/dist/esm/src/urn-registry/uuid-to-big-int.js.map +1 -0
  168. package/dist/esm/src/urn-registry/uuid-to-big-int.spec.d.ts +3 -0
  169. package/dist/esm/src/urn-registry/uuid-to-big-int.spec.d.ts.map +1 -0
  170. package/dist/esm/src/urn-registry/uuid-to-big-int.spec.js +15 -0
  171. package/dist/esm/src/urn-registry/uuid-to-big-int.spec.js.map +1 -0
  172. package/dist/esm/src/version.d.ts +5 -0
  173. package/dist/esm/src/version.d.ts.map +1 -0
  174. package/dist/esm/src/version.js +5 -0
  175. package/dist/esm/src/version.js.map +1 -0
  176. package/dist/esm/src/version.spec.d.ts +3 -0
  177. package/dist/esm/src/version.spec.d.ts.map +1 -0
  178. package/dist/esm/src/version.spec.js +7 -0
  179. package/dist/esm/src/version.spec.js.map +1 -0
  180. package/dist/esm/tests/integration.spec.d.ts +3 -0
  181. package/dist/esm/tests/integration.spec.d.ts.map +1 -0
  182. package/dist/esm/tests/integration.spec.js +6 -0
  183. package/dist/esm/tests/integration.spec.js.map +1 -0
  184. package/dist/esm/tests/network-timeout.spec.d.ts +3 -0
  185. package/dist/esm/tests/network-timeout.spec.d.ts.map +1 -0
  186. package/dist/esm/tests/network-timeout.spec.js +119 -0
  187. package/dist/esm/tests/network-timeout.spec.js.map +1 -0
  188. package/package.json +85 -0
  189. package/src/config.ts +5 -0
  190. package/src/file-box.spec.ts +480 -0
  191. package/src/file-box.ts +1042 -0
  192. package/src/file-box.type.ts +145 -0
  193. package/src/interface.spec.ts +17 -0
  194. package/src/interface.ts +47 -0
  195. package/src/misc.spec.ts +70 -0
  196. package/src/misc.ts +157 -0
  197. package/src/mod.ts +33 -0
  198. package/src/pure-functions/sized-chunk-transformer.spec.ts +52 -0
  199. package/src/pure-functions/sized-chunk-transformer.ts +49 -0
  200. package/src/qrcode.spec.ts +55 -0
  201. package/src/qrcode.ts +38 -0
  202. package/src/typings.d.ts +1 -0
  203. package/src/urn-registry/mod.ts +7 -0
  204. package/src/urn-registry/random-uuid.ts +7 -0
  205. package/src/urn-registry/uniform-resource-name-registry.spec.ts +109 -0
  206. package/src/urn-registry/uniform-resource-name-registry.ts +342 -0
  207. package/src/urn-registry/uuid-to-big-int.spec.ts +19 -0
  208. package/src/urn-registry/uuid-to-big-int.ts +16 -0
  209. package/src/version.spec.ts +9 -0
  210. package/src/version.ts +4 -0
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Huan(202110): Assignment and Resolution of Uniform Resource Names
3
+ * https://datatracker.ietf.org/wg/urn/about/
4
+ */
5
+ /**
6
+ * RFC 4122: A Universally Unique IDentifier (UUID) URN Namespace
7
+ * ------------------------------------------------------------
8
+ * This specification defines a Uniform Resource Name namespace for
9
+ * UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally
10
+ * Unique IDentifier). A UUID is 128 bits long, and can guarantee
11
+ * uniqueness across space and time. UUIDs were originally used in the
12
+ * Apollo Network Computing System and later in the Open Software
13
+ * Foundation's (OSF) Distributed Computing Environment (DCE), and then
14
+ * in Microsoft Windows platforms.
15
+ *
16
+ * The information here is meant to be a concise guide for those wishing
17
+ * to implement services using UUIDs as URNs. Nothing in this document
18
+ * should be construed to override the DCE standards that defined UUIDs.
19
+ */
20
+ /**
21
+ * RFC 2141: Uniform Resource Names (URNs) Syntax
22
+ * ----------------------------------------------
23
+ * Uniform Resource Names (URNs) are intended to serve as persistent,
24
+ * location-independent, resource identifiers. This document sets
25
+ * forward the canonical syntax for URNs. A discussion of both existing
26
+ * legacy and new namespaces and requirements for URN presentation and
27
+ * transmission are presented. Finally, there is a discussion of URN
28
+ * equivalence and how to determine it.
29
+ */
30
+ import fs from 'fs';
31
+ import os from 'os';
32
+ import path from 'path';
33
+ import { instanceToClass } from 'clone-class';
34
+ import { log } from 'brolog';
35
+ import { FileBox, } from '../file-box.js';
36
+ import { randomUuid, } from './random-uuid.js';
37
+ /**
38
+ * A UUID will be only keep for a certain time.
39
+ */
40
+ const DEFAULT_UUID_EXPIRE_MINUTES = 30;
41
+ const DEFAULT_UUID_PURGE_INTERVAL_MINUTES = 1;
42
+ class UniformResourceNameRegistry {
43
+ static processExitMap = new WeakMap();
44
+ /**
45
+ * The directory that store all UUID files
46
+ */
47
+ storeDir;
48
+ expireMilliseconds;
49
+ /**
50
+ * Key: expiretime
51
+ * Value: the array of UUID that will expires after the `expiretime` (Key)
52
+ */
53
+ uuidExpiringTable;
54
+ purgerTimer;
55
+ constructor(options = {}) {
56
+ log.verbose('UniformResourceNameRegistry', 'constructor("%s")', JSON.stringify(options));
57
+ this.uuidExpiringTable = new Map();
58
+ this.expireMilliseconds = options.expireMilliseconds ?? (DEFAULT_UUID_EXPIRE_MINUTES * 60 * 1000 * 1000);
59
+ this.storeDir = options.storeDir || path.join(os.tmpdir(), 'file-box-urn-registry.' + String(process.pid));
60
+ }
61
+ /**
62
+ * Return a FileBox Interface with the current URN Registry for conience
63
+ */
64
+ getFileBox() {
65
+ this.init();
66
+ class UUIDFileBox extends FileBox {
67
+ }
68
+ UUIDFileBox.setUuidLoader(this.load.bind(this));
69
+ UUIDFileBox.setUuidSaver(this.save.bind(this));
70
+ return UUIDFileBox;
71
+ }
72
+ /**
73
+ * init the UUID registry
74
+ *
75
+ * must be called before use.
76
+ */
77
+ init() {
78
+ log.verbose('UniformResourceNameRegistry', 'init()');
79
+ try {
80
+ const stat = fs.statSync(this.storeDir);
81
+ if (!stat.isDirectory()) {
82
+ throw new Error(this.storeDir + ' is Not a directory');
83
+ }
84
+ }
85
+ catch (e) {
86
+ if (e.code === 'ENOENT') {
87
+ fs.mkdirSync(this.storeDir, { recursive: true });
88
+ }
89
+ else {
90
+ throw e;
91
+ }
92
+ }
93
+ if (!this.purgerTimer) {
94
+ this.addProcessExitListener();
95
+ this.purgerTimer = setInterval(() => this.purgeExpiredUuid(), DEFAULT_UUID_PURGE_INTERVAL_MINUTES * 60 * 1000);
96
+ }
97
+ }
98
+ purgeExpiredUuid() {
99
+ log.verbose('UniformResourceNameRegistry', 'purgeExpiredUuid()');
100
+ const expireTimeList = [...this.uuidExpiringTable.keys()]
101
+ .sort((a, b) => Number(a) - Number(b));
102
+ for (const expireTime of expireTimeList) {
103
+ if (Date.now() < expireTime) {
104
+ // The earliest expire time is in the future
105
+ break;
106
+ }
107
+ const uuidList = this.uuidExpiringTable.get(expireTime) || [];
108
+ this.uuidExpiringTable.delete(expireTime);
109
+ for (const uuid of uuidList) {
110
+ this.purge(uuid).catch(console.error);
111
+ }
112
+ }
113
+ }
114
+ /**
115
+ * Clean up by calling this.destroy() before process exit
116
+ */
117
+ addProcessExitListener() {
118
+ log.verbose('UniformResourceNameRegistry', 'addProcessExitListener()');
119
+ const Klass = instanceToClass(this, UniformResourceNameRegistry);
120
+ /**
121
+ * If we have already registered the listener, do nothing.
122
+ */
123
+ if (Klass.processExitMap.has(this)) {
124
+ return;
125
+ }
126
+ const destroyCallback = () => this.destroy();
127
+ process.addListener('exit', destroyCallback);
128
+ Klass.processExitMap.set(this, () => process.removeListener('exit', destroyCallback));
129
+ }
130
+ uuidFileName(uuid) {
131
+ return path.join(this.storeDir, uuid + '.dat');
132
+ }
133
+ /**
134
+ * @deprecated use `load()` instead
135
+ */
136
+ async resolve(uuid) {
137
+ log.warn('UniformResourceNameRegistry', 'resolve() is deprecated: use `load()` instead.\n%s', new Error().stack);
138
+ return this.load(uuid);
139
+ }
140
+ /**
141
+ * `resolve()` can only be used once.
142
+ * after resolve(), the UUID will be not exist any more
143
+ */
144
+ async load(uuid) {
145
+ log.verbose('UniformResourceNameRegistry', 'load(%s)', uuid);
146
+ const filename = this.uuidFileName(uuid);
147
+ const stream = fs.createReadStream(filename);
148
+ await new Promise((resolve, reject) => {
149
+ stream.on('ready', resolve);
150
+ stream.on('error', reject);
151
+ });
152
+ return stream;
153
+ }
154
+ /**
155
+ * @deprecated use `save()` instead
156
+ */
157
+ async register(stream) {
158
+ log.verbose('UniformResourceNameRegistry', 'register() deprecated: use save() instead.\n%s', new Error().stack);
159
+ return this.save(stream);
160
+ }
161
+ /**
162
+ * Save the `Readable` stream and return a random UUID
163
+ * The UUID will be expired after MAX_KEEP_MINUTES
164
+ */
165
+ async save(stream) {
166
+ log.verbose('UniformResourceNameRegistry', 'save(stream)');
167
+ const uuid = randomUuid();
168
+ const fileStream = fs.createWriteStream(this.uuidFileName(uuid));
169
+ const future = new Promise((resolve, reject) => {
170
+ stream.on('end', resolve);
171
+ stream.on('error', reject);
172
+ fileStream.on('error', reject);
173
+ });
174
+ stream.pipe(fileStream);
175
+ await future;
176
+ this.addToExpiringTable(uuid);
177
+ return uuid;
178
+ }
179
+ /**
180
+ * Set a timer to execute delete callback after `expireMilliseconds`
181
+ */
182
+ addToExpiringTable(uuid) {
183
+ log.verbose('UniformResourceNameRegistry', 'addToExpiringTable(%s)', uuid);
184
+ const expireTime = Date.now() + this.expireMilliseconds;
185
+ const expireTimeInterval = DEFAULT_UUID_PURGE_INTERVAL_MINUTES * 60 * 1000;
186
+ // https://stackoverflow.com/a/22687090
187
+ const expireTimeNearestMinute = Math.ceil(expireTime / expireTimeInterval) * expireTimeInterval;
188
+ const uuidList = this.uuidExpiringTable.get(expireTime) || [];
189
+ uuidList.push(uuid);
190
+ this.uuidExpiringTable.set(expireTimeNearestMinute, uuidList);
191
+ log.silly('UniformResourceNameRegistry', 'addToExpiringTable() uuidList.length = %s, expireTime = %s', uuidList.length, expireTimeNearestMinute);
192
+ }
193
+ async purge(uuid) {
194
+ log.verbose('UniformResourceNameRegistry', 'purge(%s)', uuid);
195
+ const file = this.uuidFileName(uuid);
196
+ try {
197
+ await fs.promises.unlink(file);
198
+ log.silly('UniformResourceNameRegistry', 'purge() %s', file);
199
+ }
200
+ catch (e) {
201
+ log.warn('UniformResourceNameRegistry', 'purge() rejection:', e.message);
202
+ }
203
+ }
204
+ /**
205
+ * destroy the urn registry.
206
+ *
207
+ * This function will be called automatically at `process.on(exit)`
208
+ * however, it till need to be called before the program ends
209
+ * because there have some timers in eventloop task list
210
+ */
211
+ destroy() {
212
+ log.verbose('UniformResourceNameRegistry', 'destroy() %s UUIDs left', [...this.uuidExpiringTable.values()].flat().length);
213
+ if (this.purgerTimer) {
214
+ log.verbose('UniformResourceNameRegistry', 'destroy() clearing purger timer ...');
215
+ clearInterval(this.purgerTimer);
216
+ this.purgerTimer = undefined;
217
+ }
218
+ const Klass = instanceToClass(this, UniformResourceNameRegistry);
219
+ /**
220
+ * Remove process exit listener
221
+ */
222
+ if (Klass.processExitMap.has(this)) {
223
+ log.verbose('UniformResourceNameRegistry', 'destroy() remove process `exit` listener ...');
224
+ const fn = Klass.processExitMap.get(this);
225
+ Klass.processExitMap.delete(this);
226
+ fn && fn();
227
+ }
228
+ /**
229
+ * Clean up all the files
230
+ */
231
+ log.verbose('UniformResourceNameRegistry', 'destroy() fs.rmSync(%s) ...', this.storeDir);
232
+ try {
233
+ /**
234
+ * Huan(202110):
235
+ * Check for the `this.uuidDir` exist or not
236
+ * when we are running unit tests, we might instanciate multiple UniformResourceNameRegistry
237
+ * which will cause the `this.destroy()` to be registered multiple times
238
+ */
239
+ fs.statSync(this.storeDir);
240
+ fs.rmSync(this.storeDir, { recursive: true });
241
+ log.verbose('UniformResourceNameRegistry', 'destroy() fs.rmSync(%s) done', this.storeDir);
242
+ }
243
+ catch (e) {
244
+ if (e.code === 'ENOENT') {
245
+ log.verbose('UniformResourceNameRegistry', 'destroy() %s not exist', this.storeDir);
246
+ return;
247
+ }
248
+ log.warn('UniformResourceNameRegistry', 'destroy() fs.rmSync(%s) exception: %s', e.message);
249
+ }
250
+ }
251
+ }
252
+ export { UniformResourceNameRegistry };
253
+ //# sourceMappingURL=uniform-resource-name-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uniform-resource-name-registry.js","sourceRoot":"","sources":["../../../../src/urn-registry/uniform-resource-name-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env -S node --no-warnings --loader ts-node/esm
2
+ export {};
3
+ //# sourceMappingURL=uniform-resource-name-registry.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uniform-resource-name-registry.spec.d.ts","sourceRoot":"","sources":["../../../../src/urn-registry/uniform-resource-name-registry.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env -S node --no-warnings --loader ts-node/esm
2
+ import { test, sinon, } from 'tstest';
3
+ import { FileBox } from '../file-box.js';
4
+ import { UniformResourceNameRegistry } from './uniform-resource-name-registry.js';
5
+ test('UniformResourceNameRegistry class', async (t) => {
6
+ const QRCODE = 'test qrcode';
7
+ const urnRegistry = new UniformResourceNameRegistry();
8
+ await urnRegistry.init();
9
+ const fileBox = FileBox.fromQRCode(QRCODE);
10
+ const stream = await fileBox.toStream();
11
+ const uuid = await urnRegistry.save(stream);
12
+ const stream2 = await urnRegistry.load(uuid);
13
+ t.ok(stream2, 'should load stream');
14
+ const fileBox2 = FileBox.fromStream(stream2, 'test');
15
+ const qrcode = await fileBox2.toQRCode();
16
+ t.equal(qrcode, QRCODE, 'should get back the qrcode data');
17
+ await t.resolves(() => urnRegistry.load(uuid), 'should not reject when load a UUID again');
18
+ await urnRegistry.destroy();
19
+ });
20
+ test('expireMilliseconds: in time', async (t) => {
21
+ const expireMilliseconds = 3;
22
+ const urnRegistry = new UniformResourceNameRegistry({
23
+ expireMilliseconds,
24
+ });
25
+ await urnRegistry.init();
26
+ const uuid = await urnRegistry.save(await FileBox.fromQRCode('qr').toStream());
27
+ await new Promise(resolve => setTimeout(resolve, 1));
28
+ await t.resolves(() => urnRegistry.load(uuid), `should not expire after 1ms (with ${expireMilliseconds}ms expire)`);
29
+ await urnRegistry.destroy();
30
+ });
31
+ test('expireMilliseconds: time out', async (t) => {
32
+ const sandbox = sinon.createSandbox({
33
+ useFakeTimers: true,
34
+ });
35
+ const expireMilliseconds = 10 * 60 * 1000; // 10 minute
36
+ const urnRegistry = new UniformResourceNameRegistry({
37
+ expireMilliseconds,
38
+ });
39
+ await urnRegistry.init();
40
+ /**
41
+ * Time: 0
42
+ */
43
+ const uuid1 = await urnRegistry.save(await FileBox.fromQRCode('qr').toStream());
44
+ await t.resolves(() => urnRegistry.load(uuid1), 'should load uuid1 successfully');
45
+ /**
46
+ * Time: 5
47
+ */
48
+ await sandbox.clock.tickAsync(5 * 60 * 1000);
49
+ const uuid2 = await urnRegistry.save(await FileBox.fromQRCode('qr2').toStream());
50
+ await t.resolves(() => urnRegistry.load(uuid1), 'should load uuid1 successfully after 5 minutes');
51
+ await t.resolves(() => urnRegistry.load(uuid2), 'should load uuid2 successfully');
52
+ /**
53
+ * Time: 11
54
+ */
55
+ await sandbox.clock.tickAsync(6 * 60 * 1000);
56
+ await t.rejects(() => urnRegistry.load(uuid1), 'should load uuid1 fail because it is expired');
57
+ await t.resolves(() => urnRegistry.load(uuid2), 'should load uuid2 successfully 6 minutes after it has been saved');
58
+ /**
59
+ * Time 20
60
+ */
61
+ await sandbox.clock.tickAsync(9 * 60 * 1000);
62
+ await t.rejects(() => urnRegistry.load(uuid2), 'should load uuid2 fail because it is expired');
63
+ await urnRegistry.destroy();
64
+ sandbox.restore();
65
+ });
66
+ test('URN FileBox helper smoke testing', async (t) => {
67
+ const QRCODE = 'test qrcode';
68
+ const urnRegistry = new UniformResourceNameRegistry();
69
+ const UUIDFileBox = urnRegistry.getFileBox();
70
+ const uuid = await UUIDFileBox
71
+ .fromQRCode(QRCODE)
72
+ .toUuid();
73
+ const qrcode = await UUIDFileBox
74
+ .fromUuid(uuid)
75
+ .toQRCode();
76
+ t.equal(qrcode, QRCODE, 'should get back the qrcode data');
77
+ urnRegistry.destroy();
78
+ });
79
+ //# sourceMappingURL=uniform-resource-name-registry.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uniform-resource-name-registry.spec.js","sourceRoot":"","sources":["../../../../src/urn-registry/uniform-resource-name-registry.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Convert UUID to BigInt
3
+ * @param uuid
4
+ * @returns BigInt
5
+ */
6
+ declare function uuidToBigInt(uuid: string): BigInt;
7
+ export { uuidToBigInt, };
8
+ //# sourceMappingURL=uuid-to-big-int.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid-to-big-int.d.ts","sourceRoot":"","sources":["../../../../src/urn-registry/uuid-to-big-int.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,iBAAS,YAAY,CAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAK3C;AAED,OAAO,EACL,YAAY,GACb,CAAA"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Convert UUID to BigInt
3
+ * @param uuid
4
+ * @returns BigInt
5
+ */
6
+ function uuidToBigInt(uuid) {
7
+ // credit: https://stackoverflow.com/a/58014300/1123955
8
+ const hexBytes = `0x${uuid.replace(/-/g, '')}`;
9
+ const bigInteger = BigInt(hexBytes);
10
+ return bigInteger;
11
+ }
12
+ export { uuidToBigInt, };
13
+ //# sourceMappingURL=uuid-to-big-int.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid-to-big-int.js","sourceRoot":"","sources":["../../../../src/urn-registry/uuid-to-big-int.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,SAAS,YAAY,CAAE,IAAY;IACjC,uDAAuD;IACvD,MAAM,QAAQ,GAAM,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAA;IACjD,MAAM,UAAU,GAAI,MAAM,CAAC,QAAQ,CAAC,CAAA;IACpC,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,OAAO,EACL,YAAY,GACb,CAAA"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env -S node --no-warnings --loader ts-node/esm
2
+ export {};
3
+ //# sourceMappingURL=uuid-to-big-int.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid-to-big-int.spec.d.ts","sourceRoot":"","sources":["../../../../src/urn-registry/uuid-to-big-int.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env -S node --no-warnings --loader ts-node/esm
2
+ import { test } from 'tstest';
3
+ import { uuidToBigInt } from './uuid-to-big-int.js';
4
+ test('uuidToBigInt() Nil UUID', async (t) => {
5
+ const uuid = '00000000-0000-0000-0000-000000000000';
6
+ const bigInt = uuidToBigInt(uuid);
7
+ t.equal(bigInt.toString(), '0', 'should get zero for a Nil UUID');
8
+ });
9
+ test('uuidToBigInt() Nil UUID', async (t) => {
10
+ const UUID = '00bd7c03-a690-48d3-a1fe-1314574e4fc1';
11
+ const EXPECTED = BigInt('0x00bd7c03a69048d3a1fe1314574e4fc1');
12
+ const bigInt = uuidToBigInt(UUID);
13
+ t.equal(bigInt, EXPECTED, 'should convert UUID right');
14
+ });
15
+ //# sourceMappingURL=uuid-to-big-int.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid-to-big-int.spec.js","sourceRoot":"","sources":["../../../../src/urn-registry/uuid-to-big-int.spec.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,EAAE,MAAO,QAAQ,CAAA;AAE9B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEnD,IAAI,CAAC,yBAAyB,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;IACxC,MAAM,IAAI,GAAG,sCAAsC,CAAA;IACnD,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,gCAAgC,CAAC,CAAA;AACnE,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,yBAAyB,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;IACxC,MAAM,IAAI,GAAG,sCAAsC,CAAA;IACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,oCAAoC,CAAC,CAAA;IAE7D,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,2BAA2B,CAAC,CAAA;AACxD,CAAC,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * This file was auto generated from scripts/generate-version.sh
3
+ */
4
+ export declare const VERSION: string;
5
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/version.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAAgB,CAAA"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * This file was auto generated from scripts/generate-version.sh
3
+ */
4
+ export const VERSION = '1.7.0';
5
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/version.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAW,OAAO,CAAA"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env -S node --no-warnings --loader ts-node/esm
2
+ export {};
3
+ //# sourceMappingURL=version.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.spec.d.ts","sourceRoot":"","sources":["../../../src/version.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env -S node --no-warnings --loader ts-node/esm
2
+ import { test } from 'tstest';
3
+ import { VERSION } from './version.js';
4
+ test('Make sure the VERSION is fresh in source code', async (t) => {
5
+ t.equal(VERSION, '0.0.0', 'version should be 0.0.0 in source code, only updated before publish to NPM');
6
+ });
7
+ //# sourceMappingURL=version.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.spec.js","sourceRoot":"","sources":["../../../src/version.spec.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,EAAE,MAAO,QAAQ,CAAA;AAE9B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,IAAI,CAAC,+CAA+C,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;IAC9D,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,4EAA4E,CAAC,CAAA;AACzG,CAAC,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env -S node --no-warnings --loader ts-node/esm
2
+ export {};
3
+ //# sourceMappingURL=integration.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.spec.d.ts","sourceRoot":"","sources":["../../../tests/integration.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env -S node --no-warnings --loader ts-node/esm
2
+ import { test } from 'tstest';
3
+ test('integration test', async (t) => {
4
+ t.pass('tbw');
5
+ });
6
+ //# sourceMappingURL=integration.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.spec.js","sourceRoot":"","sources":["../../../tests/integration.spec.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,EAAE,MAAO,QAAQ,CAAA;AAE9B,IAAI,CAAC,kBAAkB,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;IACjC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACf,CAAC,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env -S node --no-warnings --loader ts-node/esm
2
+ export {};
3
+ //# sourceMappingURL=network-timeout.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network-timeout.spec.d.ts","sourceRoot":"","sources":["../../../tests/network-timeout.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env -S node --no-warnings --loader ts-node/esm
2
+ import { createServer } from 'http';
3
+ import { setTimeout } from 'timers/promises';
4
+ import { sinon, test } from 'tstest';
5
+ import { FileBox } from '../src/mod.js';
6
+ import { HTTP_TIMEOUT } from '../src/config.js';
7
+ test('slow network stall HTTP_TIMEOUT', async (t) => {
8
+ const sandbox = sinon.createSandbox();
9
+ sandbox.useFakeTimers({
10
+ now: Date.now(),
11
+ shouldAdvanceTime: true,
12
+ shouldClearNativeTimers: true,
13
+ toFake: ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'nextTick'],
14
+ });
15
+ t.jobs = 3;
16
+ const port = Math.floor(Math.random() * (65535 - 49152 + 1)) + 49152;
17
+ const URL = {
18
+ NOT_TIMEOUT: '/not_timeout',
19
+ READY: '/ready',
20
+ TIMEOUT: '/timeout',
21
+ };
22
+ /* eslint @typescript-eslint/no-misused-promises:off */
23
+ const server = createServer(async (req, res) => {
24
+ res.write(Buffer.from('This is the first chunk of data.'));
25
+ if (req.url === URL.NOT_TIMEOUT) {
26
+ await setTimeout(HTTP_TIMEOUT * 0.5);
27
+ res.write(Buffer.from('This is the second chunk of data.'));
28
+ await setTimeout(HTTP_TIMEOUT * 0.9);
29
+ }
30
+ else {
31
+ await setTimeout(HTTP_TIMEOUT + 100);
32
+ }
33
+ // console.debug(`${new Date().toLocaleTimeString()} call res.end "${req.url}"`)
34
+ res.end(Buffer.from('All data end.'));
35
+ });
36
+ const host = await new Promise((resolve) => {
37
+ server.listen(port, '127.0.0.1', () => {
38
+ const addr = server.address();
39
+ // console.debug(`Server is listening on port ${JSON.stringify(addr)}`)
40
+ resolve(`http://127.0.0.1:${addr.port}`);
41
+ });
42
+ });
43
+ t.teardown(() => {
44
+ // console.debug('teardown')
45
+ server.close();
46
+ sandbox.restore();
47
+ });
48
+ /** eslint @typescript-eslint/no-floating-promises:off */
49
+ t.test('should not timeout', async (t) => {
50
+ const url = `${host}${URL.NOT_TIMEOUT}`;
51
+ const dataSpy = sandbox.spy();
52
+ const errorSpy = sandbox.spy();
53
+ // console.debug(`${new Date().toLocaleTimeString()} Start request "${url}" ...`)
54
+ const start = Date.now();
55
+ const stream = await FileBox.fromUrl(url).toStream();
56
+ stream.once('error', errorSpy).on('data', dataSpy);
57
+ await sandbox.clock.tickAsync(1);
58
+ t.ok(dataSpy.calledOnce, `should get chunk 1 (${Date.now() - start} passed)`);
59
+ t.ok(errorSpy.notCalled, `should not get error (${Date.now() - start} passed)`);
60
+ // FIXME: tickAsync does not work on socket timeout
61
+ await new Promise((resolve) => {
62
+ stream.once('error', resolve).on('close', resolve);
63
+ // resolve(setTimeout(HTTP_TIMEOUT))
64
+ });
65
+ await sandbox.clock.tickAsync(1);
66
+ // await sandbox.clock.tickAsync(HTTP_TIMEOUT)
67
+ // t.comment('recv data count:', dataSpy.callCount)
68
+ // t.comment('recv error count:', errorSpy.callCount)
69
+ t.ok(dataSpy.calledThrice, `should get chunk 3 after TIMEOUT ${HTTP_TIMEOUT} (${Date.now() - start} passed)`);
70
+ t.ok(errorSpy.notCalled, `should not get error after TIMEOUT ${HTTP_TIMEOUT} (${Date.now() - start} passed)`);
71
+ t.end();
72
+ }).catch(t.threw);
73
+ /** eslint @typescript-eslint/no-floating-promises:off */
74
+ t.test('should timeout', async (t) => {
75
+ const url = `${host}${URL.TIMEOUT}`;
76
+ const dataSpy = sandbox.spy();
77
+ const errorSpy = sandbox.spy();
78
+ // console.debug(`${new Date().toLocaleTimeString()} Start request "${url}" ...`)
79
+ const start = Date.now();
80
+ const stream = await FileBox.fromUrl(url).toStream();
81
+ stream.once('error', errorSpy).once('data', dataSpy);
82
+ // .on('error', (e) => {
83
+ // console.error(`on error for req "${url}":`, e.stack)
84
+ // })
85
+ // .on('data', (d: Buffer) => {
86
+ // console.error(`on data for req "${url}":`, d.toString())
87
+ // })
88
+ await sandbox.clock.tickAsync(1);
89
+ // t.comment('recv data count:', dataSpy.callCount)
90
+ // t.comment('recv error count:', errorSpy.callCount)
91
+ t.ok(dataSpy.calledOnce, `should get chunk 1 (${Date.now() - start} passed)`);
92
+ t.ok(errorSpy.notCalled, `should not get error (${Date.now() - start} passed)`);
93
+ // FIXME: tickAsync does not work on socket timeout
94
+ await new Promise((resolve) => {
95
+ stream.once('error', resolve).on('close', resolve);
96
+ // resolve(setTimeout(HTTP_TIMEOUT))
97
+ });
98
+ await sandbox.clock.tickAsync(1);
99
+ // await sandbox.clock.tickAsync(HTTP_TIMEOUT)
100
+ // t.comment('recv data count:', dataSpy.callCount)
101
+ // t.comment('recv error count:', errorSpy.callCount)
102
+ t.ok(errorSpy.calledOnce, `should get error after TIMEOUT ${HTTP_TIMEOUT} (${Date.now() - start} passed)`);
103
+ t.end();
104
+ }).catch(t.threw);
105
+ /** eslint @typescript-eslint/no-floating-promises:off */
106
+ t.test('ready should timeout', async (t) => {
107
+ const url = `${host}${URL.READY}`;
108
+ const errorSpy = sandbox.spy();
109
+ // console.debug(`${new Date().toLocaleTimeString()} Start request "${url}" ...`)
110
+ const start = Date.now();
111
+ const fileBox = FileBox.fromUrl(url);
112
+ await fileBox.ready().catch(errorSpy);
113
+ await sandbox.clock.tickAsync(1);
114
+ // t.comment('recv error count:', errorSpy.callCount)
115
+ t.ok(errorSpy.calledOnce, `should get error after TIMEOUT ${HTTP_TIMEOUT} (${Date.now() - start} passed)`);
116
+ t.end();
117
+ }).catch(t.threw);
118
+ });
119
+ //# sourceMappingURL=network-timeout.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network-timeout.spec.js","sourceRoot":"","sources":["../../../tests/network-timeout.spec.ts"],"names":[],"mappings":"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"}