Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions .pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
---
changelog:
- date: 2026-02-11
version: v10.2.7
changes:
- type: improvement
text: "PubNubFile to support `ReadableFile` type for React Native target platform."
- date: 2026-01-13
version: v10.2.6
changes:
Expand Down Expand Up @@ -1384,7 +1389,7 @@ supported-platforms:
- 'Ubuntu 14.04 and up'
- 'Windows 7 and up'
version: 'Pubnub Javascript for Node'
version: '10.2.6'
version: '10.2.7'
sdks:
- full-name: PubNub Javascript SDK
short-name: Javascript
Expand All @@ -1400,7 +1405,7 @@ sdks:
- distribution-type: source
distribution-repository: GitHub release
package-name: pubnub.js
location: https://github.com/pubnub/javascript/archive/refs/tags/v10.2.6.zip
location: https://github.com/pubnub/javascript/archive/refs/tags/v10.2.7.zip
requires:
- name: 'agentkeepalive'
min-version: '3.5.2'
Expand Down Expand Up @@ -2071,7 +2076,7 @@ sdks:
- distribution-type: library
distribution-repository: GitHub release
package-name: pubnub.js
location: https://github.com/pubnub/javascript/releases/download/v10.2.6/pubnub.10.2.6.js
location: https://github.com/pubnub/javascript/releases/download/v10.2.7/pubnub.10.2.7.js
requires:
- name: 'agentkeepalive'
min-version: '3.5.2'
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## v10.2.7
February 11 2026

#### Modified
- PubNubFile to support `ReadableFile` type for React Native target platform.

## v10.2.6
January 13 2026

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ Watch [Getting Started with PubNub JS SDK](https://app.dashcam.io/replay/64ee0d2
npm install pubnub
```
* or download one of our builds from our CDN:
* https://cdn.pubnub.com/sdk/javascript/pubnub.10.2.6.js
* https://cdn.pubnub.com/sdk/javascript/pubnub.10.2.6.min.js
* https://cdn.pubnub.com/sdk/javascript/pubnub.10.2.7.js
* https://cdn.pubnub.com/sdk/javascript/pubnub.10.2.7.min.js

2. Configure your keys:

Expand Down
2 changes: 1 addition & 1 deletion dist/web/pubnub.js
Original file line number Diff line number Diff line change
Expand Up @@ -5438,7 +5438,7 @@
return base.PubNubFile;
},
get version() {
return '10.2.6';
return '10.2.7';
},
getVersion() {
return this.version;
Expand Down
2 changes: 1 addition & 1 deletion dist/web/pubnub.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/core/components/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ const makeConfiguration = (base, setupCryptoModule) => {
return base.PubNubFile;
},
get version() {
return '10.2.6';
return '10.2.7';
},
getVersion() {
return this.version;
Expand Down
48 changes: 46 additions & 2 deletions lib/file/modules/react-native.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,52 @@ class PubNubFile {
const contents = file.data;
fileMimeType = file.mimeType;
fileName = file.name;
fileData = new File([contents], fileName, { type: fileMimeType });
contentLength = fileData.size;
// create a ReadableFile wrapper for ArrayBuffer data
if (contents instanceof ArrayBuffer || ArrayBuffer.isView(contents)) {
// Create ReadableFile wrapper for ArrayBuffer
const arrayBuffer = contents instanceof ArrayBuffer ? contents : contents.buffer;
contentLength = arrayBuffer.byteLength;
fileData = {
arrayBuffer: () => __awaiter(this, void 0, void 0, function* () { return arrayBuffer; }),
blob: () => __awaiter(this, void 0, void 0, function* () {
throw new Error('toBlob() is not supported in React Native environment. Use toArrayBuffer() instead.');
}),
text: () => __awaiter(this, void 0, void 0, function* () {
const decoder = new TextDecoder();
return decoder.decode(arrayBuffer);
}),
};
}
else if (typeof contents === 'string') {
// Handle string data
const encoder = new TextEncoder();
const arrayBuffer = encoder.encode(contents).buffer;
contentLength = arrayBuffer.byteLength;
fileData = {
arrayBuffer: () => __awaiter(this, void 0, void 0, function* () { return arrayBuffer; }),
blob: () => __awaiter(this, void 0, void 0, function* () { return new Blob([contents], { type: fileMimeType }); }),
text: () => __awaiter(this, void 0, void 0, function* () { return contents; }),
};
}
else if (contents instanceof Blob) {
// Handle Blob data
contentLength = contents.size;
fileData = {
arrayBuffer: () => __awaiter(this, void 0, void 0, function* () { return yield contents.arrayBuffer(); }),
blob: () => __awaiter(this, void 0, void 0, function* () { return contents; }),
text: () => __awaiter(this, void 0, void 0, function* () { return yield contents.text(); }),
};
}
else {
// Fallback: Try to use File constructor (may still fail in some environments)
try {
fileData = new File([contents], fileName, { type: fileMimeType });
contentLength = fileData.size;
}
catch (error) {
throw new Error(`Unable to create file from provided data type. ArrayBuffer, Blob, or string expected.Error: ${error}`);
}
}
}
else if ('uri' in file) {
fileMimeType = file.mimeType;
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pubnub",
"version": "10.2.6",
"version": "10.2.7",
"author": "PubNub <[email protected]>",
"description": "Publish & Subscribe Real-time Messaging with PubNub",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion src/core/components/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ export const makeConfiguration = (
return base.PubNubFile;
},
get version(): string {
return '10.2.6';
return '10.2.7';
},
getVersion(): string {
return this.version;
Expand Down
49 changes: 47 additions & 2 deletions src/file/modules/react-native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,53 @@ export class PubNubFile implements PubNubFileInterface {

fileMimeType = file.mimeType;
fileName = file.name;
fileData = new File([contents], fileName, { type: fileMimeType });
contentLength = fileData.size;

// create a ReadableFile wrapper for ArrayBuffer data
if (contents instanceof ArrayBuffer || ArrayBuffer.isView(contents)) {
// Create ReadableFile wrapper for ArrayBuffer
const arrayBuffer = contents instanceof ArrayBuffer ? contents : contents.buffer;
contentLength = arrayBuffer.byteLength;

fileData = {
arrayBuffer: async () => arrayBuffer,
blob: async () => {
throw new Error('toBlob() is not supported in React Native environment. Use toArrayBuffer() instead.');
},
text: async () => {
const decoder = new TextDecoder();
return decoder.decode(arrayBuffer);
},
} as ReadableFile;
} else if (typeof contents === 'string') {
// Handle string data
const encoder = new TextEncoder();
const arrayBuffer = encoder.encode(contents).buffer;
contentLength = arrayBuffer.byteLength;

fileData = {
arrayBuffer: async () => arrayBuffer,
blob: async () => new Blob([contents], { type: fileMimeType }),
text: async () => contents,
} as ReadableFile;
} else if (contents instanceof Blob) {
// Handle Blob data
contentLength = contents.size;
fileData = {
arrayBuffer: async () => await contents.arrayBuffer(),
blob: async () => contents,
text: async () => await contents.text(),
} as ReadableFile;
} else {
// Fallback: Try to use File constructor (may still fail in some environments)
try {
fileData = new File([contents], fileName, { type: fileMimeType });
contentLength = fileData.size;
} catch (error) {
throw new Error(
`Unable to create file from provided data type. ArrayBuffer, Blob, or string expected.Error: ${error}`,
);
}
}
} else if ('uri' in file) {
fileMimeType = file.mimeType;
fileName = file.name;
Expand Down
64 changes: 64 additions & 0 deletions test/dist/react-native.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -412,5 +412,69 @@ describe('#distribution test (rkt-native)', function () {
pubnub.File.create({});
}).to.throw();
});

it('should wrap string data with readable file support', async function () {
const fileData = {
data: 'Hello React Native',
name: 'string-test.txt',
mimeType: 'text/plain'
};

const file = pubnub.File.create(fileData);

expect(file).to.be.an('object');
expect(file).to.have.property('name').equal('string-test.txt');
expect(file).to.have.property('mimeType').equal('text/plain');

const text = await file.toString();
expect(text).to.equal('Hello React Native');

const arrayBuffer = await file.toArrayBuffer();
const decoded = new TextDecoder().decode(arrayBuffer);
expect(decoded).to.equal('Hello React Native');

const blob = await file.toBlob();
expect(blob).to.be.instanceOf(Blob);
expect(blob.type).to.equal('text/plain');
});

it('should wrap ArrayBuffer data and disallow toBlob in React Native', async function () {
const encoder = new TextEncoder();
const arrayBuffer = encoder.encode('ArrayBuffer content').buffer;
const fileData = {
data: arrayBuffer,
name: 'arraybuffer-test.txt',
mimeType: 'text/plain'
};

const file = pubnub.File.create(fileData);

const buffer = await file.toArrayBuffer();
const decoded = new TextDecoder().decode(buffer);
expect(decoded).to.equal('ArrayBuffer content');

try {
await file.toBlob();
throw new Error('Expected toBlob to throw');
} catch (error) {
expect(error.message).to.equal(
'toBlob() is not supported in React Native environment. Use toArrayBuffer() instead.'
);
}
});

it('should accept ArrayBufferView data and expose content via toArrayBuffer', async function () {
const dataView = new Uint8Array([80, 117, 98, 78, 117, 98]);
const fileData = {
data: dataView,
name: 'view-test.txt',
mimeType: 'text/plain'
};

const file = pubnub.File.create(fileData);
const buffer = await file.toArrayBuffer();
const decoded = new TextDecoder().decode(buffer);
expect(decoded).to.equal('PubNub');
});
});
});
Loading