CoreFileSystemWritableFileStream.js 6.3 KB

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