Skip to content

Commit 70dd804

Browse files
authored
feat: align main exports across node and browser (#259)
* feat: align main exports across node and browser - add shared FilecoinPinAPI contract and mirror exports in index entries - consolidate type exports, fix missing dist/index.js - add isomorphic package import test covering createCarFromPath behavior - update vitest config to run all tests via multiple projects. - individual projects can still be ran via `npm run test:unit`, `npm run test:integration`, `npm run test:browser` Related to #182 * fix: vitest matches all integration tests * test: fix isomorphic import test * test: fix package import test for windows * chore: remove playwright alias * chore: remove default export * fix: less export duplication * test: fix test after removing default export * chore: minor cleanup * fix: remove initializeSynapse from FilecoinPinAPI
1 parent 5dd4954 commit 70dd804

File tree

7 files changed

+202
-8
lines changed

7 files changed

+202
-8
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ node ./dist/cli.js
268268
npm run test # All tests
269269
npm run test:unit # Unit tests only
270270
npm run test:integration # Integration tests
271+
npm run test:browser # Browser tests
271272
npm run lint:fix # Fix formatting
272273
```
273274

package.json

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
"types": "dist/index.d.ts",
88
"exports": {
99
".": {
10+
"browser": {
11+
"types": "./dist/index.browser.d.ts",
12+
"default": "./dist/index.browser.js"
13+
},
1014
"types": "./dist/index.d.ts",
1115
"default": "./dist/index.js"
1216
},
@@ -75,9 +79,10 @@
7579
"build": "tsc && node scripts/write-version.mjs",
7680
"dev": "tsx watch src/cli.ts server",
7781
"start": "node dist/cli.js server",
78-
"test": "npm run lint && npm run typecheck && npm run test:unit && npm run test:integration",
79-
"test:unit": "vitest run src/test/unit",
80-
"test:integration": "vitest run src/test/integration",
82+
"test": "npm run lint && npm run typecheck && vitest run",
83+
"test:unit": "vitest run --project unit",
84+
"test:integration": "vitest run --project integration",
85+
"test:browser": "vitest run --project browser",
8186
"test:watch": "vitest",
8287
"lint": "tsc && biome check --no-errors-on-unmatched --files-ignore-unknown=true .",
8388
"lint:fix": "biome check --no-errors-on-unmatched --files-ignore-unknown=true --fix .",
@@ -122,10 +127,12 @@
122127
"@ipld/dag-cbor": "^9.2.5",
123128
"@types/node": "^24.5.1",
124129
"@types/semver": "^7.5.8",
125-
"@vitest/coverage-v8": "^4.0.12",
130+
"@vitest/browser-playwright": "^4.0.13",
131+
"@vitest/coverage-v8": "^4.0.13",
132+
"playwright-chromium": "^1.56.1",
126133
"tsx": "^4.20.5",
127134
"typescript": "^5.9.2",
128-
"vitest": "^4.0.12"
135+
"vitest": "^4.0.13"
129136
},
130137
"publishConfig": {
131138
"access": "public"

src/index-types.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { getDataSetPieces, getDetailedDataSet, listDataSets } from './core/data-set/index.js'
2+
import type { getPaymentStatus, validatePaymentCapacity } from './core/payments/index.js'
3+
import type { cleanupSynapseService, setupSynapse } from './core/synapse/index.js'
4+
import type { createCarFromFile, createCarFromFiles } from './core/unixfs/browser-car-builder.js'
5+
import type { createCarFromPath } from './core/unixfs/car-builder.js'
6+
import type { checkUploadReadiness, executeUpload } from './core/upload/index.js'
7+
8+
export interface FilecoinPinAPI {
9+
getDataSetPieces: typeof getDataSetPieces
10+
getDetailedDataSet: typeof getDetailedDataSet
11+
listDataSets: typeof listDataSets
12+
getPaymentStatus: typeof getPaymentStatus
13+
validatePaymentCapacity: typeof validatePaymentCapacity
14+
cleanupSynapseService: typeof cleanupSynapseService
15+
setupSynapse: typeof setupSynapse
16+
createCarFromFile: typeof createCarFromFile
17+
createCarFromFiles: typeof createCarFromFiles
18+
createCarFromPath: typeof createCarFromPath
19+
checkUploadReadiness: typeof checkUploadReadiness
20+
executeUpload: typeof executeUpload
21+
}
22+
23+
export type { ProviderInfo } from '@filoz/synapse-sdk'
24+
export type {
25+
DataSetPiecesResult,
26+
DataSetSummary,
27+
GetDataSetPiecesOptions,
28+
ListDataSetsOptions,
29+
PieceInfo,
30+
Warning as DataSetWarning,
31+
} from './core/data-set/index.js'
32+
export type { PaymentCapacityCheck, PaymentStatus } from './core/payments/index.js'
33+
export type {
34+
CreateStorageContextOptions,
35+
DatasetOptions,
36+
SynapseService,
37+
SynapseSetupConfig,
38+
} from './core/synapse/index.js'
39+
export type { CreateCarOptions, CreateCarResult } from './core/unixfs/car-builder.js'
40+
export type {
41+
SynapseUploadOptions,
42+
SynapseUploadResult,
43+
UploadExecutionOptions,
44+
UploadExecutionResult,
45+
UploadProgressEvents,
46+
UploadReadinessOptions,
47+
UploadReadinessResult,
48+
} from './core/upload/index.js'

src/index.browser.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* High-level API for filecoin-pin
3+
*
4+
* This file exports the most common functions and types for interacting with the filecoin-pin library in the browser.
5+
* For more advanced use cases, you can import from the granular `./core/*` modules.
6+
*/
7+
import * as dataSet from './core/data-set/index.js'
8+
import * as payments from './core/payments/index.js'
9+
import * as synapse from './core/synapse/index.js'
10+
import * as browserCar from './core/unixfs/browser-car-builder.js'
11+
import type { CreateCarOptions } from './core/unixfs/car-builder.js'
12+
import * as upload from './core/upload/index.js'
13+
import type { FilecoinPinAPI } from './index-types.js'
14+
15+
export * from './index-types.js'
16+
17+
const publicApi = {
18+
getDataSetPieces: dataSet.getDataSetPieces,
19+
getDetailedDataSet: dataSet.getDetailedDataSet,
20+
listDataSets: dataSet.listDataSets,
21+
getPaymentStatus: payments.getPaymentStatus,
22+
validatePaymentCapacity: payments.validatePaymentCapacity,
23+
cleanupSynapseService: synapse.cleanupSynapseService,
24+
setupSynapse: synapse.setupSynapse,
25+
createCarFromFile: browserCar.createCarFromFile,
26+
createCarFromFiles: browserCar.createCarFromFiles,
27+
/**
28+
* Not available in the browser; use createCarFromFile or createCarFromFiles.
29+
*
30+
* @remarks Node-only helper; preserved for API parity with the Node entrypoint.
31+
* @throws Always throws in browser builds.
32+
*/
33+
createCarFromPath: (_path: string, _options?: CreateCarOptions): never => {
34+
throw new Error('Function not available in the browser.')
35+
},
36+
checkUploadReadiness: upload.checkUploadReadiness,
37+
executeUpload: upload.executeUpload,
38+
} satisfies FilecoinPinAPI
39+
40+
export const {
41+
getDataSetPieces,
42+
getDetailedDataSet,
43+
listDataSets,
44+
getPaymentStatus,
45+
validatePaymentCapacity,
46+
cleanupSynapseService,
47+
setupSynapse,
48+
createCarFromFile,
49+
createCarFromFiles,
50+
createCarFromPath,
51+
checkUploadReadiness,
52+
executeUpload,
53+
} = publicApi

src/index.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* High-level API for filecoin-pin
3+
*
4+
* This file exports the most common functions and types for interacting with the filecoin-pin library in Node.js.
5+
* For more advanced use cases, you can import from the granular `./core/*` modules.
6+
*/
7+
import { createCarFromPath as createCarFromPathCore } from './core/unixfs/car-builder.js'
8+
import * as browser from './index.browser.js'
9+
import type { FilecoinPinAPI } from './index-types.js'
10+
11+
export * from './index-types.js'
12+
13+
const publicApi = {
14+
...browser,
15+
createCarFromPath: createCarFromPathCore,
16+
} satisfies FilecoinPinAPI
17+
18+
export const {
19+
getDataSetPieces,
20+
getDetailedDataSet,
21+
listDataSets,
22+
getPaymentStatus,
23+
validatePaymentCapacity,
24+
cleanupSynapseService,
25+
setupSynapse,
26+
createCarFromFile,
27+
createCarFromFiles,
28+
createCarFromPath,
29+
checkUploadReadiness,
30+
executeUpload,
31+
} = publicApi
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { describe, expect, it } from 'vitest'
2+
3+
describe('filecoin-pin isomorphic import', () => {
4+
it('doesnt throw when importing filecoin-pin', async () => {
5+
await expect(import('filecoin-pin')).resolves.toBeDefined()
6+
})
7+
8+
it('browser and node.js exports are handled properly', async () => {
9+
const { createCarFromPath, createCarFromFiles, createCarFromFile } = await import('filecoin-pin')
10+
11+
expect(typeof createCarFromPath).toBe('function')
12+
expect(typeof createCarFromFile).toBe('function')
13+
expect(typeof createCarFromFiles).toBe('function')
14+
if (typeof window !== 'undefined') {
15+
expect(() => createCarFromPath('foo')).toThrow('Function not available in the browser.')
16+
} else {
17+
await expect(createCarFromPath('foo')).rejects.toThrow('ENOENT')
18+
}
19+
})
20+
})

vitest.config.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,45 @@
1+
import { playwright } from '@vitest/browser-playwright'
12
import { defineConfig } from 'vitest/config'
23

34
export default defineConfig({
45
test: {
56
globals: true,
6-
environment: 'node',
77
root: '.',
8-
include: ['src/**/*.test.ts'],
9-
setupFiles: ['src/test/setup.ts'],
8+
projects: [
9+
{
10+
// unit tests for node.js (also isomorphic tests)
11+
test: {
12+
name: 'unit',
13+
environment: 'node',
14+
include: ['src/test/unit/**/*.test.ts', 'src/test/**/*.iso.test.ts'],
15+
exclude: ['src/test/**/*.browser.test.ts'],
16+
setupFiles: ['src/test/setup.ts'],
17+
},
18+
},
19+
{
20+
// integration tests
21+
test: {
22+
name: 'integration',
23+
environment: 'node',
24+
include: ['src/test/integration/**/*.test.ts'],
25+
exclude: ['src/test/**/*.browser.test.ts'],
26+
setupFiles: ['src/test/setup.ts'],
27+
},
28+
},
29+
{
30+
// browser tests (also isomorphic tests)
31+
test: {
32+
name: 'browser',
33+
include: ['src/test/**/*.browser.test.ts', 'src/test/**/*.iso.test.ts'],
34+
browser: {
35+
enabled: true,
36+
provider: playwright(),
37+
instances: [{ browser: 'chromium' }],
38+
headless: true,
39+
screenshotFailures: false,
40+
},
41+
},
42+
},
43+
],
1044
},
1145
})

0 commit comments

Comments
 (0)