CoreFileSystemWritableFileStream.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.CoreFileSystemWritableFileStream = void 0;
  4. const buffer_1 = require("../internal/buffer");
  5. const util_1 = require("./util");
  6. const constants_1 = require("../node/constants");
  7. const WS = (typeof WritableStream === 'undefined' ? require('stream/web').WritableStream : WritableStream);
  8. /**
  9. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream
  10. */
  11. class CoreFileSystemWritableFileStream extends WS {
  12. constructor(core, path, keepExistingData = false) {
  13. let fd;
  14. super({
  15. start: controller => {
  16. // Open file for writing
  17. const flags = keepExistingData ? constants_1.FLAGS['r+'] : constants_1.FLAGS.w;
  18. try {
  19. fd = core.open(path, flags, 438 /* MODE.FILE */);
  20. }
  21. catch (error) {
  22. if (error && typeof error === 'object' && error.code === "EACCES" /* ERROR_CODE.EACCES */) {
  23. throw (0, util_1.newNotAllowedError)();
  24. }
  25. throw error;
  26. }
  27. },
  28. write: async (chunk) => {
  29. await this._write(chunk);
  30. },
  31. close: async () => {
  32. if (!this._closed && this._fd !== undefined) {
  33. core.close(this._fd);
  34. this._closed = true;
  35. }
  36. },
  37. abort: async () => {
  38. if (!this._closed && this._fd !== undefined) {
  39. core.close(this._fd);
  40. this._closed = true;
  41. }
  42. },
  43. });
  44. this._position = 0;
  45. this._closed = false;
  46. this._core = core;
  47. this._path = path;
  48. this._fd = fd;
  49. }
  50. /**
  51. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream/seek
  52. */
  53. async seek(position) {
  54. if (this._closed) {
  55. throw new DOMException('The stream is closed.', 'InvalidStateError');
  56. }
  57. this._position = position;
  58. }
  59. /**
  60. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream/truncate
  61. */
  62. async truncate(size) {
  63. if (this._closed) {
  64. throw new DOMException('The stream is closed.', 'InvalidStateError');
  65. }
  66. try {
  67. const link = this._core.getResolvedLinkOrThrow(this._path);
  68. const node = link.getNode();
  69. node.truncate(size);
  70. }
  71. catch (error) {
  72. if (error && typeof error === 'object' && error.code === "EACCES" /* ERROR_CODE.EACCES */) {
  73. throw (0, util_1.newNotAllowedError)();
  74. }
  75. throw error;
  76. }
  77. }
  78. async write(chunkOrParams) {
  79. await this._write(chunkOrParams);
  80. }
  81. async _write(chunkOrParams) {
  82. if (this._closed) {
  83. throw new DOMException('The stream is closed.', 'InvalidStateError');
  84. }
  85. if (this._fd === undefined) {
  86. throw new DOMException('The stream is not ready.', 'InvalidStateError');
  87. }
  88. try {
  89. if (this._isParams(chunkOrParams)) {
  90. const params = chunkOrParams;
  91. switch (params.type) {
  92. case 'write': {
  93. if (params.data !== undefined) {
  94. const buffer = this._dataToBuffer(params.data);
  95. const position = params.position !== undefined ? params.position : this._position;
  96. const written = this._core.write(this._fd, buffer, 0, buffer.length, position);
  97. if (params.position === undefined) {
  98. this._position += written;
  99. }
  100. }
  101. break;
  102. }
  103. case 'seek': {
  104. if (params.position !== undefined) {
  105. this._position = params.position;
  106. }
  107. break;
  108. }
  109. case 'truncate': {
  110. if (params.size !== undefined) {
  111. await this.truncate(params.size);
  112. }
  113. break;
  114. }
  115. }
  116. }
  117. else {
  118. // Direct data write
  119. const buffer = this._dataToBuffer(chunkOrParams);
  120. const written = this._core.write(this._fd, buffer, 0, buffer.length, this._position);
  121. this._position += written;
  122. }
  123. }
  124. catch (error) {
  125. if (error && typeof error === 'object' && error.code === "EACCES" /* ERROR_CODE.EACCES */) {
  126. throw (0, util_1.newNotAllowedError)();
  127. }
  128. throw error;
  129. }
  130. }
  131. _isParams(chunk) {
  132. return !!(chunk && typeof chunk === 'object' && 'type' in chunk);
  133. }
  134. _dataToBuffer(data) {
  135. if (typeof data === 'string') {
  136. return buffer_1.Buffer.from(data, 'utf8');
  137. }
  138. if (data instanceof buffer_1.Buffer) {
  139. return data;
  140. }
  141. if (data instanceof ArrayBuffer) {
  142. return buffer_1.Buffer.from(data);
  143. }
  144. if (ArrayBuffer.isView(data)) {
  145. return buffer_1.Buffer.from(data.buffer, data.byteOffset, data.byteLength);
  146. }
  147. if (data instanceof Blob) {
  148. // For Blob, we would need to read it asynchronously
  149. // This is a simplified implementation
  150. throw new Error('Blob data type not fully supported in this implementation');
  151. }
  152. throw new Error('Unsupported data type');
  153. }
  154. }
  155. exports.CoreFileSystemWritableFileStream = CoreFileSystemWritableFileStream;
  156. //# sourceMappingURL=CoreFileSystemWritableFileStream.js.map