2
2
3
3
const {
4
4
DateNow,
5
+ FunctionPrototypeApply,
5
6
NumberIsNaN,
6
7
ObjectDefineProperties,
8
+ ObjectSetPrototypeOf,
7
9
StringPrototypeToWellFormed,
10
+ Symbol,
8
11
SymbolToStringTag,
9
12
} = primordials ;
10
13
11
14
const {
12
15
Blob,
16
+ TransferableBlob,
13
17
} = require ( 'internal/blob' ) ;
14
18
15
19
const {
@@ -20,6 +24,7 @@ const {
20
24
21
25
const {
22
26
codes : {
27
+ ERR_INVALID_THIS ,
23
28
ERR_MISSING_ARGS ,
24
29
} ,
25
30
} = require ( 'internal/errors' ) ;
@@ -28,13 +33,32 @@ const {
28
33
inspect,
29
34
} = require ( 'internal/util/inspect' ) ;
30
35
31
- class File extends Blob {
32
- /** @type {string } */
33
- #name;
36
+ const {
37
+ kClone,
38
+ kDeserialize,
39
+ } = require ( 'internal/worker/js_transferable' ) ;
40
+
41
+ const kState = Symbol ( 'state' ) ;
42
+
43
+ function isFile ( object ) {
44
+ return object ?. [ kState ] !== undefined ;
45
+ }
34
46
35
- /** @type {number } */
36
- #lastModified;
47
+ class FileState {
48
+ name ;
49
+ lastModified ;
50
+
51
+ /**
52
+ * @param {string } name
53
+ * @param {number } lastModified
54
+ */
55
+ constructor ( name , lastModified ) {
56
+ this . name = name ;
57
+ this . lastModified = lastModified ;
58
+ }
59
+ }
37
60
61
+ class File extends Blob {
38
62
constructor ( fileBits , fileName , options = kEmptyObject ) {
39
63
if ( arguments . length < 2 ) {
40
64
throw new ERR_MISSING_ARGS ( 'fileBits' , 'fileName' ) ;
@@ -55,16 +79,21 @@ class File extends Blob {
55
79
lastModified = DateNow ( ) ;
56
80
}
57
81
58
- this . #name = StringPrototypeToWellFormed ( `${ fileName } ` ) ;
59
- this . #lastModified = lastModified ;
82
+ this [ kState ] = new FileState ( StringPrototypeToWellFormed ( `${ fileName } ` ) , lastModified ) ;
60
83
}
61
84
62
85
get name ( ) {
63
- return this . #name;
86
+ if ( ! isFile ( this ) )
87
+ throw new ERR_INVALID_THIS ( 'File' ) ;
88
+
89
+ return this [ kState ] . name ;
64
90
}
65
91
66
92
get lastModified ( ) {
67
- return this . #lastModified;
93
+ if ( ! isFile ( this ) )
94
+ throw new ERR_INVALID_THIS ( 'File' ) ;
95
+
96
+ return this [ kState ] . lastModified ;
68
97
}
69
98
70
99
[ kInspect ] ( depth , options ) {
@@ -80,12 +109,32 @@ class File extends Blob {
80
109
return `File ${ inspect ( {
81
110
size : this . size ,
82
111
type : this . type ,
83
- name : this . # name,
84
- lastModified : this . # lastModified,
112
+ name : this [ kState ] . name ,
113
+ lastModified : this [ kState ] . lastModified ,
85
114
} , opts ) } `;
86
115
}
116
+
117
+ [ kClone ] ( ) {
118
+ return {
119
+ data : { ...super [ kClone ] ( ) . data , ...this [ kState ] } ,
120
+ deserializeInfo : 'internal/file:TransferableFile' ,
121
+ } ;
122
+ }
123
+
124
+ [ kDeserialize ] ( data ) {
125
+ super [ kDeserialize ] ( data ) ;
126
+
127
+ this [ kState ] = new FileState ( data . name , data . lastModified ) ;
128
+ }
129
+ }
130
+
131
+ function TransferableFile ( handle , length , type = '' ) {
132
+ FunctionPrototypeApply ( TransferableBlob , this , [ handle , length , type ] ) ;
87
133
}
88
134
135
+ ObjectSetPrototypeOf ( TransferableFile . prototype , File . prototype ) ;
136
+ ObjectSetPrototypeOf ( TransferableFile , File ) ;
137
+
89
138
ObjectDefineProperties ( File . prototype , {
90
139
name : kEnumerableProperty ,
91
140
lastModified : kEnumerableProperty ,
@@ -98,4 +147,5 @@ ObjectDefineProperties(File.prototype, {
98
147
99
148
module . exports = {
100
149
File,
150
+ TransferableFile,
101
151
} ;
0 commit comments