@heyputer/puter.js 2.1.15 → 2.2.4
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/puter.cjs +2 -2
- package/index.d.ts +0 -2
- package/package.json +2 -3
- package/src/index.js +100 -82
- package/src/lib/utils.js +42 -55
- package/src/modules/AI.js +8 -204
- package/src/modules/Apps.js +42 -11
- package/src/modules/Auth.js +6 -5
- package/src/modules/Debug.js +4 -4
- package/src/modules/Drivers.js +12 -17
- package/src/modules/FileSystem/index.js +9 -24
- package/src/modules/Hosting.js +5 -4
- package/src/modules/KV.js +67 -11
- package/src/modules/OS.js +6 -5
- package/src/modules/Perms.js +4 -3
- package/src/modules/PuterDialog.js +2 -2
- package/src/modules/UI.js +44 -28
- package/src/modules/UsageLimitDialog.js +208 -0
- package/types/modules/ai.d.ts +0 -10
- package/types/modules/apps.d.ts +24 -15
- package/types/modules/auth.d.ts +3 -1
- package/types/modules/filesystem.d.ts +0 -2
- package/types/modules/kv.d.ts +10 -0
- package/types/modules/networking.d.ts +1 -1
- package/types/modules/os.d.ts +2 -7
- package/types/modules/ui.d.ts +10 -7
- package/types/modules/util.d.ts +0 -1
- package/types/modules/workers.d.ts +9 -10
- package/types/puter.d.ts +1 -7
- package/src/lib/filesystem/APIFS.js +0 -65
- package/src/lib/filesystem/CacheFS.js +0 -243
- package/src/lib/filesystem/PostMessageFS.js +0 -40
- package/src/lib/filesystem/definitions.js +0 -40
- package/src/modules/Threads.js +0 -72
- package/src/services/APIAccess.js +0 -46
- package/src/services/FSRelay.js +0 -20
- package/src/services/Filesystem.js +0 -137
- package/src/services/NoPuterYet.js +0 -20
- package/src/services/XDIncoming.js +0 -44
- package/types/modules/threads.d.ts +0 -27
package/index.d.ts
CHANGED
|
@@ -11,7 +11,6 @@ import type { KV, KVIncrementPath, KVPair } from './types/modules/kv.d.ts';
|
|
|
11
11
|
import type { Networking, PSocket, PTLSSocket } from './types/modules/networking.d.ts';
|
|
12
12
|
import type { OS } from './types/modules/os.d.ts';
|
|
13
13
|
import type { Perms } from './types/modules/perms.d.ts';
|
|
14
|
-
import type Threads from './types/modules/threads.d.ts';
|
|
15
14
|
import type { AlertButton, AppConnection, AppConnectionCloseEvent, CancelAwarePromise, ContextMenuItem, ContextMenuOptions, DirectoryPickerOptions, FilePickerOptions, LaunchAppOptions, MenuItem, MenubarOptions, ThemeData, UI, WindowOptions } from './types/modules/ui.d.ts';
|
|
16
15
|
import type Util, { UtilRPC } from './types/modules/util.d.ts';
|
|
17
16
|
import type { WorkerDeployment, WorkerInfo, WorkersHandler } from './types/modules/workers.d.ts';
|
|
@@ -93,7 +92,6 @@ export type {
|
|
|
93
92
|
Speech2TxtOptions,
|
|
94
93
|
Subdomain,
|
|
95
94
|
ThemeData,
|
|
96
|
-
Threads,
|
|
97
95
|
ToolSchema,
|
|
98
96
|
Txt2ImgOptions,
|
|
99
97
|
Txt2SpeechCallable,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heyputer/puter.js",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.4",
|
|
4
4
|
"description": "Puter.js - A JavaScript library for interacting with Puter services.",
|
|
5
5
|
"homepage": "https://developer.puter.com",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -42,7 +42,6 @@
|
|
|
42
42
|
"webpack-cli": "^5.1.4"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@heyputer/kv.js": "^0.2.1"
|
|
46
|
-
"@heyputer/putility": "^1.1.1"
|
|
45
|
+
"@heyputer/kv.js": "^0.2.1"
|
|
47
46
|
}
|
|
48
47
|
}
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import putility from '@heyputer/putility';
|
|
2
|
-
|
|
3
1
|
import kvjs from '@heyputer/kv.js';
|
|
4
2
|
import APICallLogger from './lib/APICallLogger.js';
|
|
5
3
|
import path from './lib/path.js';
|
|
@@ -20,16 +18,72 @@ import { PTLSSocket } from './modules/networking/PTLS.js';
|
|
|
20
18
|
import { pFetch } from './modules/networking/requests.js';
|
|
21
19
|
import OS from './modules/OS.js';
|
|
22
20
|
import Perms from './modules/Perms.js';
|
|
23
|
-
import Threads from './modules/Threads.js';
|
|
24
21
|
import UI from './modules/UI.js';
|
|
25
22
|
import Util from './modules/Util.js';
|
|
26
23
|
import { WorkersHandler } from './modules/Workers.js';
|
|
27
|
-
import { APIAccessService } from './services/APIAccess.js';
|
|
28
|
-
import { FilesystemService } from './services/Filesystem.js';
|
|
29
|
-
import { FSRelayService } from './services/FSRelay.js';
|
|
30
|
-
import { NoPuterYetService } from './services/NoPuterYet.js';
|
|
31
|
-
import { XDIncomingService } from './services/XDIncoming.js';
|
|
32
24
|
|
|
25
|
+
class SimpleLogger {
|
|
26
|
+
constructor (fields = {}) {
|
|
27
|
+
this.fieldsObj = fields;
|
|
28
|
+
this.enabled = new Set();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
on (category) {
|
|
32
|
+
this.enabled.add(category);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
fields (extra = {}) {
|
|
36
|
+
return new SimpleLogger({ ...this.fieldsObj, ...extra });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
info (...args) {
|
|
40
|
+
console.log(...this._prefix(), ...args);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
warn (...args) {
|
|
44
|
+
console.warn(...this._prefix(), ...args);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
error (...args) {
|
|
48
|
+
console.error(...this._prefix(), ...args);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
debug (...args) {
|
|
52
|
+
console.debug(...this._prefix(), ...args);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
_prefix () {
|
|
56
|
+
const entries = Object.entries(this.fieldsObj);
|
|
57
|
+
if ( !entries.length ) return [];
|
|
58
|
+
return [`[${ entries.map(([k, v]) => `${k}=${v}`).join(' ')}]`];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
class Lock {
|
|
63
|
+
constructor () {
|
|
64
|
+
this.locked = false;
|
|
65
|
+
this.queue = [];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async acquire () {
|
|
69
|
+
if ( !this.locked ) {
|
|
70
|
+
this.locked = true;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
await new Promise(resolve => this.queue.push(resolve));
|
|
75
|
+
this.locked = true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
release () {
|
|
79
|
+
const next = this.queue.shift();
|
|
80
|
+
if ( next ) {
|
|
81
|
+
next();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this.locked = false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
33
87
|
// TODO: This is for a safe-guard below; we should check if we can
|
|
34
88
|
// generalize this behavior rather than hard-coding it.
|
|
35
89
|
// (using defaultGUIOrigin breaks locally-hosted apps)
|
|
@@ -115,7 +169,6 @@ const puterInit = (function () {
|
|
|
115
169
|
this.registerModule('apps', Apps);
|
|
116
170
|
this.registerModule('ai', AI);
|
|
117
171
|
this.registerModule('kv', KV);
|
|
118
|
-
this.registerModule('threads', Threads);
|
|
119
172
|
this.registerModule('perms', Perms);
|
|
120
173
|
this.registerModule('drivers', Drivers);
|
|
121
174
|
this.registerModule('debug', Debug);
|
|
@@ -135,15 +188,6 @@ const puterInit = (function () {
|
|
|
135
188
|
|
|
136
189
|
// "modules" in puter.js are external interfaces for the developer
|
|
137
190
|
this.modules_ = [];
|
|
138
|
-
// "services" in puter.js are used by modules and may interact with each other
|
|
139
|
-
const context = new putility.libs.context.Context()
|
|
140
|
-
.follow(this, ['env', 'util', 'authToken', 'APIOrigin', 'appID']);
|
|
141
|
-
|
|
142
|
-
context.puter = this;
|
|
143
|
-
|
|
144
|
-
this.services = new putility.system.ServiceManager({ context });
|
|
145
|
-
this.context = context;
|
|
146
|
-
context.services = this.services;
|
|
147
191
|
|
|
148
192
|
// Holds the query parameters found in the current URL
|
|
149
193
|
let URLParams = new URLSearchParams(globalThis.location?.search);
|
|
@@ -261,57 +305,15 @@ const puterInit = (function () {
|
|
|
261
305
|
|
|
262
306
|
// === START :: Logger ===
|
|
263
307
|
|
|
264
|
-
// logger
|
|
265
|
-
let logger = new
|
|
266
|
-
|
|
267
|
-
// logs can be toggled based on categories
|
|
268
|
-
logger = new putility.libs.log.CategorizedToggleLogger({ delegate: logger });
|
|
269
|
-
const cat_logger = logger;
|
|
270
|
-
|
|
271
|
-
// create facade for easy logging
|
|
272
|
-
this.logger = new putility.libs.log.LoggerFacade({
|
|
273
|
-
impl: logger,
|
|
274
|
-
cat: cat_logger,
|
|
275
|
-
});
|
|
308
|
+
// Basic logger replacement (console-based)
|
|
309
|
+
let logger = new SimpleLogger();
|
|
310
|
+
this.logger = logger;
|
|
276
311
|
|
|
277
312
|
// Initialize API call logger
|
|
278
313
|
this.apiCallLogger = new APICallLogger({
|
|
279
314
|
enabled: false, // Disabled by default
|
|
280
315
|
});
|
|
281
316
|
|
|
282
|
-
// === START :: Services === //
|
|
283
|
-
|
|
284
|
-
this.services.register('no-puter-yet', NoPuterYetService);
|
|
285
|
-
this.services.register('filesystem', FilesystemService);
|
|
286
|
-
this.services.register('api-access', APIAccessService);
|
|
287
|
-
this.services.register('xd-incoming', XDIncomingService);
|
|
288
|
-
if ( this.env !== 'app' ) {
|
|
289
|
-
this.services.register('fs-relay', FSRelayService);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// When api-access is initialized, bind `.authToken` and
|
|
293
|
-
// `.APIOrigin` as a 1-1 mapping with the `puter` global
|
|
294
|
-
(async () => {
|
|
295
|
-
await this.services.wait_for_init(['api-access']);
|
|
296
|
-
const svc_apiAccess = this.services.get('api-access');
|
|
297
|
-
|
|
298
|
-
svc_apiAccess.auth_token = this.authToken;
|
|
299
|
-
svc_apiAccess.api_origin = this.APIOrigin;
|
|
300
|
-
[
|
|
301
|
-
['authToken', 'auth_token'],
|
|
302
|
-
['APIOrigin', 'api_origin'],
|
|
303
|
-
].forEach(([k1, k2]) => {
|
|
304
|
-
Object.defineProperty(this, k1, {
|
|
305
|
-
get () {
|
|
306
|
-
return svc_apiAccess[k2];
|
|
307
|
-
},
|
|
308
|
-
set (v) {
|
|
309
|
-
svc_apiAccess[k2] = v;
|
|
310
|
-
},
|
|
311
|
-
});
|
|
312
|
-
});
|
|
313
|
-
})();
|
|
314
|
-
|
|
315
317
|
// === Start :: Modules === //
|
|
316
318
|
|
|
317
319
|
// The SDK is running in the Puter GUI (i.e. 'gui')
|
|
@@ -365,31 +367,27 @@ const puterInit = (function () {
|
|
|
365
367
|
|
|
366
368
|
// Add prefix logger (needed to happen after modules are initialized)
|
|
367
369
|
(async () => {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
delegate: logger,
|
|
372
|
-
prefix: `[${
|
|
370
|
+
try {
|
|
371
|
+
const whoami = await this.auth.whoami();
|
|
372
|
+
const prefix = `[${
|
|
373
373
|
whoami?.app_name ?? this.appInstanceID ?? 'HOST'
|
|
374
|
-
}]
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
374
|
+
}]`;
|
|
375
|
+
logger = logger.fields({ prefix });
|
|
376
|
+
this.logger = logger;
|
|
377
|
+
} catch (error) {
|
|
378
|
+
if ( this.debugMode ) {
|
|
379
|
+
console.error('Failed to initialize prefix logger', error);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
378
382
|
})();
|
|
379
383
|
|
|
380
384
|
// Lock to prevent multiple requests to `/rao`
|
|
381
|
-
this.lock_rao_ = new
|
|
385
|
+
this.lock_rao_ = new Lock();
|
|
382
386
|
// Promise that resolves when it's okay to request `/rao`
|
|
383
|
-
this.p_can_request_rao_ =
|
|
387
|
+
this.p_can_request_rao_ = Promise.resolve();
|
|
384
388
|
// Flag that indicates if a request to `/rao` has been made
|
|
385
389
|
this.rao_requested_ = false;
|
|
386
390
|
|
|
387
|
-
// In case we're already auth'd, request `/rao`
|
|
388
|
-
(async () => {
|
|
389
|
-
await this.services.wait_for_init(['api-access']);
|
|
390
|
-
this.p_can_request_rao_.resolve();
|
|
391
|
-
})();
|
|
392
|
-
|
|
393
391
|
this.net = {
|
|
394
392
|
generateWispV1URL: async () => {
|
|
395
393
|
const { token: wispToken, server: wispServer } = (await (await fetch(`${this.APIOrigin }/wisp/relay-token/create`, {
|
|
@@ -457,7 +455,7 @@ const puterInit = (function () {
|
|
|
457
455
|
}
|
|
458
456
|
|
|
459
457
|
registerModule (name, cls, parameters = {}) {
|
|
460
|
-
const instance = new cls(this
|
|
458
|
+
const instance = new cls(this, parameters);
|
|
461
459
|
instance.puter = this;
|
|
462
460
|
this.modules_.push(name);
|
|
463
461
|
this[name] = instance;
|
|
@@ -518,6 +516,25 @@ const puterInit = (function () {
|
|
|
518
516
|
this.updateSubmodules();
|
|
519
517
|
};
|
|
520
518
|
|
|
519
|
+
runWhenPuterHappensCallbacks = function () {
|
|
520
|
+
if ( this.env !== 'gui' ) return;
|
|
521
|
+
if ( ! globalThis.when_puter_happens ) return;
|
|
522
|
+
|
|
523
|
+
const callbacks = Array.isArray(globalThis.when_puter_happens)
|
|
524
|
+
? globalThis.when_puter_happens
|
|
525
|
+
: [globalThis.when_puter_happens];
|
|
526
|
+
|
|
527
|
+
for ( const fn of callbacks ) {
|
|
528
|
+
try {
|
|
529
|
+
fn({ puter: this });
|
|
530
|
+
} catch ( error ) {
|
|
531
|
+
if ( this.debugMode ) {
|
|
532
|
+
console.error('when_puter_happens callback failed', error);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
|
|
521
538
|
resetAuthToken = function () {
|
|
522
539
|
this.authToken = null;
|
|
523
540
|
// If the SDK is running on a 3rd-party site or an app, then save the authToken in localStorage
|
|
@@ -785,6 +802,7 @@ const puterInit = (function () {
|
|
|
785
802
|
export const puter = puterInit();
|
|
786
803
|
export default puter;
|
|
787
804
|
globalThis.puter = puter;
|
|
805
|
+
puter.runWhenPuterHappensCallbacks();
|
|
788
806
|
|
|
789
807
|
puter.tools = [];
|
|
790
808
|
/**
|
|
@@ -863,4 +881,4 @@ globalThis.addEventListener && globalThis.addEventListener('message', async (eve
|
|
|
863
881
|
puter.puterAuthState.resolver = null;
|
|
864
882
|
};
|
|
865
883
|
}
|
|
866
|
-
});
|
|
884
|
+
});
|
package/src/lib/utils.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FileReaderPoly } from "./polyfills/fileReaderPoly.js";
|
|
2
|
+
import { showUsageLimitDialog } from "../modules/UsageLimitDialog.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Parses a given response text into a JSON object. If the parsing fails due to invalid JSON format,
|
|
@@ -65,6 +66,16 @@ function uuidv4 () {
|
|
|
65
66
|
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
const createDeferred = () => {
|
|
70
|
+
let resolve;
|
|
71
|
+
let reject;
|
|
72
|
+
const promise = new Promise((res, rej) => {
|
|
73
|
+
resolve = res;
|
|
74
|
+
reject = rej;
|
|
75
|
+
});
|
|
76
|
+
return { promise, resolve, reject };
|
|
77
|
+
};
|
|
78
|
+
|
|
68
79
|
/**
|
|
69
80
|
* Initializes and returns an XMLHttpRequest object configured for a specific API endpoint, method, and headers.
|
|
70
81
|
*
|
|
@@ -266,11 +277,11 @@ function make_driver_method (arg_defs, driverInterface, driverName, driverMethod
|
|
|
266
277
|
}
|
|
267
278
|
|
|
268
279
|
async function driverCall (options, driverInterface, driverName, driverMethod, driverArgs, settings) {
|
|
269
|
-
const
|
|
280
|
+
const deferred = createDeferred();
|
|
270
281
|
|
|
271
282
|
driverCall_(options,
|
|
272
|
-
|
|
273
|
-
|
|
283
|
+
deferred.resolve,
|
|
284
|
+
deferred.reject,
|
|
274
285
|
driverInterface,
|
|
275
286
|
driverName,
|
|
276
287
|
driverMethod,
|
|
@@ -279,7 +290,7 @@ async function driverCall (options, driverInterface, driverName, driverMethod, d
|
|
|
279
290
|
undefined,
|
|
280
291
|
settings);
|
|
281
292
|
|
|
282
|
-
return await
|
|
293
|
+
return await deferred.promise;
|
|
283
294
|
}
|
|
284
295
|
|
|
285
296
|
// This function encapsulates the logic for sending a driver call request
|
|
@@ -368,14 +379,22 @@ async function driverCall_ (
|
|
|
368
379
|
is_stream = true;
|
|
369
380
|
const Stream = async function* Stream () {
|
|
370
381
|
while ( !response_complete ) {
|
|
371
|
-
const
|
|
372
|
-
signal_stream_update =
|
|
373
|
-
await
|
|
382
|
+
const signal = createDeferred();
|
|
383
|
+
signal_stream_update = signal.resolve;
|
|
384
|
+
await signal.promise;
|
|
374
385
|
if ( response_complete ) break;
|
|
375
386
|
while ( lines_received.length > 0 ) {
|
|
376
387
|
const line = lines_received.shift();
|
|
377
388
|
if ( line.trim() === '' ) continue;
|
|
378
389
|
const lineObject = (JSON.parse(line));
|
|
390
|
+
|
|
391
|
+
// Check for usage limit errors in streaming responses
|
|
392
|
+
if ( lineObject?.error?.code === 'insufficient_funds' || lineObject?.metadata?.usage_limited === true ) {
|
|
393
|
+
if ( puter.env === 'web' ) {
|
|
394
|
+
showUsageLimitDialog('You have reached your usage limit for this account.<br>Please upgrade to continue.');
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
379
398
|
if ( typeof (lineObject.text) === 'string' ) {
|
|
380
399
|
Object.defineProperty(lineObject, 'toString', {
|
|
381
400
|
enumerable: false,
|
|
@@ -452,6 +471,16 @@ async function driverCall_ (
|
|
|
452
471
|
});
|
|
453
472
|
}
|
|
454
473
|
|
|
474
|
+
// Check for usage limit errors and show upgrade dialog
|
|
475
|
+
const isInsufficientFunds = (response.target?.status === 402) ||
|
|
476
|
+
(resp?.error?.code === 'insufficient_funds') ||
|
|
477
|
+
(resp?.error?.status === 402);
|
|
478
|
+
const isUsageLimited = resp?.metadata?.usage_limited === true;
|
|
479
|
+
|
|
480
|
+
if ( (isInsufficientFunds || isUsageLimited) && puter.env === 'web' ) {
|
|
481
|
+
showUsageLimitDialog('Your account has not enough funding to complete this request.<br>Please upgrade to continue.');
|
|
482
|
+
}
|
|
483
|
+
|
|
455
484
|
// HTTP Error - unauthorized
|
|
456
485
|
if ( response.status === 401 || resp?.code === 'token_auth_failed' ) {
|
|
457
486
|
if ( resp?.code === 'token_auth_failed' && puter.env === 'web' ) {
|
|
@@ -543,58 +572,16 @@ async function driverCall_ (
|
|
|
543
572
|
args: driverArgs,
|
|
544
573
|
auth_token: puter.authToken,
|
|
545
574
|
}));
|
|
546
|
-
}
|
|
547
575
|
|
|
548
|
-
class TeePromise {
|
|
549
|
-
static STATUS_PENDING = {};
|
|
550
|
-
static STATUS_RUNNING = {};
|
|
551
|
-
static STATUS_DONE = {};
|
|
552
|
-
constructor () {
|
|
553
|
-
this.status_ = this.constructor.STATUS_PENDING;
|
|
554
|
-
this.donePromise = new Promise((resolve, reject) => {
|
|
555
|
-
this.doneResolve = resolve;
|
|
556
|
-
this.doneReject = reject;
|
|
557
|
-
});
|
|
558
|
-
}
|
|
559
|
-
get status () {
|
|
560
|
-
return this.status_;
|
|
561
|
-
}
|
|
562
|
-
set status (status) {
|
|
563
|
-
this.status_ = status;
|
|
564
|
-
if ( status === this.constructor.STATUS_DONE ) {
|
|
565
|
-
this.doneResolve();
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
resolve (value) {
|
|
569
|
-
this.status_ = this.constructor.STATUS_DONE;
|
|
570
|
-
this.doneResolve(value);
|
|
571
|
-
}
|
|
572
|
-
awaitDone () {
|
|
573
|
-
return this.donePromise;
|
|
574
|
-
}
|
|
575
|
-
then (fn, rfn) {
|
|
576
|
-
return this.donePromise.then(fn, rfn);
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
reject (err) {
|
|
580
|
-
this.status_ = this.constructor.STATUS_DONE;
|
|
581
|
-
this.doneReject(err);
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
* @deprecated use then() instead
|
|
586
|
-
*/
|
|
587
|
-
onComplete (fn) {
|
|
588
|
-
return this.then(fn);
|
|
589
|
-
}
|
|
590
576
|
}
|
|
591
577
|
|
|
592
578
|
async function blob_to_url (blob) {
|
|
593
|
-
const tp = new TeePromise();
|
|
594
579
|
const reader = new (globalThis.FileReader || FileReaderPoly)();
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
580
|
+
return await new Promise((resolve, reject) => {
|
|
581
|
+
reader.onloadend = () => resolve(reader.result);
|
|
582
|
+
reader.onerror = reject;
|
|
583
|
+
reader.readAsDataURL(blob);
|
|
584
|
+
});
|
|
598
585
|
}
|
|
599
586
|
|
|
600
587
|
function blobToDataUri (blob) {
|
|
@@ -625,5 +612,5 @@ function arrayBufferToDataUri (arrayBuffer) {
|
|
|
625
612
|
}
|
|
626
613
|
|
|
627
614
|
export {
|
|
628
|
-
arrayBufferToDataUri, blob_to_url, blobToDataUri, driverCall, handle_error, handle_resp, initXhr, make_driver_method, parseResponse, setupXhrEventHandlers,
|
|
615
|
+
arrayBufferToDataUri, blob_to_url, blobToDataUri, driverCall, handle_error, handle_resp, initXhr, make_driver_method, parseResponse, setupXhrEventHandlers, uuidv4
|
|
629
616
|
};
|