Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(remote): initial #51

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
18 changes: 18 additions & 0 deletions packages/remote/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../.eslintrc.js"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
15 changes: 15 additions & 0 deletions packages/remote/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
testRunner: 'jasmine2',
displayName: 'lens',
preset: '../../jest.preset.js',
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
},
},
transform: {
'^.+\\.[tj]s$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/packages/lens',
}
30 changes: 30 additions & 0 deletions packages/remote/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "@frp-ts/remote",
"version": "1.0.0-alpha.14",
"description": "Remote Data utilities for frp-ts properties",
"typedocMain": "./src/index.ts",
"author": "raveclassic",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/raveclassic/frp-ts.git"
},
"bugs": {
"url": "https://github.com/raveclassic/frp-ts/issues"
},
"homepage": "https://github.com/raveclassic/frp-ts#readme",
"scripts": {},
"private": false,
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"tslib": "^2.3.1"
},
"dependencies": {
"@frp-ts/core": "^1.0.0-alpha.14"
},
"devDependencies": {
"tslib": "^2.3.1"
}
}
41 changes: 41 additions & 0 deletions packages/remote/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"root": "packages/remote",
"sourceRoot": "packages/remote/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nrwl/js:tsc",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/packages/remote",
"main": "packages/remote/src/index.ts",
"tsConfig": "packages/remote/tsconfig.lib.json",
"assets": ["packages/remote/*.md"]
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["packages/remote/**/*.ts"]
}
},
"test": {
"executor": "@nrwl/jest:jest",
"outputs": ["coverage/packages/remote"],
"options": {
"jestConfig": "packages/remote/jest.config.js",
"passWithNoTests": true,
"codeCoverage": true
}
},
"deploy": {
"executor": "ngx-deploy-npm:deploy",
"options": {
"access": "public",
"noBuild": true
}
}
},
"tags": []
}
21 changes: 21 additions & 0 deletions packages/remote/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export * as remoteData from './remote-data'
export {
RemotePending,
RemoteFailure,
RemoteSuccess,
RemoteData,
RemoteDataValue,
RemoteDataError,
pending,
failure,
success,
combine as combineRemoteData,
} from './remote-data'

export * as remoteProperty from './remote-property'
export {
RemoteProperty,
RemotePropertyError,
RemotePropertyValue,
combine as combineRemoteProperty,
} from './remote-property'
12 changes: 12 additions & 0 deletions packages/remote/src/remote-data/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export {
RemotePending,
RemoteFailure,
RemoteSuccess,
RemoteData,
RemoteDataValue,
RemoteDataError,
pending,
failure,
success,
combine,
} from './remote-data'
59 changes: 59 additions & 0 deletions packages/remote/src/remote-data/remote-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
export interface RemotePending {
readonly kind: 'RemotePending'
}
export const pending: RemoteData<never, never> = {
kind: 'RemotePending',
}

export interface RemoteFailure<Error> {
readonly kind: 'RemoteFailure'
readonly error: Error
}
export const failure = <Error = never, Value = never>(error: Error): RemoteData<Error, Value> => ({
kind: 'RemoteFailure',
error,
})

export interface RemoteSuccess<Value> {
readonly kind: 'RemoteSuccess'
readonly value: Value
}
export const success = <Error = never, Value = never>(value: Value): RemoteData<Error, Value> => ({
kind: 'RemoteSuccess',
value,
})

export type RemoteData<Error, Value> = RemotePending | RemoteFailure<Error> | RemoteSuccess<Value>

export type RemoteDataError<Target> = Target extends RemoteFailure<infer Error> ? Error : never
export type RemoteDataValue<Target> = Target extends RemoteSuccess<infer Value> ? Value : never

export type MapRemoteDataListToValues<Inputs extends readonly RemoteData<unknown, unknown>[]> = {
readonly [Index in keyof Inputs]: RemoteDataValue<Inputs[Index]>
}
type MapRemoteDataListToErrors<Inputs extends readonly RemoteData<unknown, unknown>[]> = {
readonly [Index in keyof Inputs]: RemoteDataError<Inputs[Index]>
}

export function combine<Inputs extends readonly RemoteData<unknown, unknown>[], Result>(
...args: [...Inputs, (...values: MapRemoteDataListToValues<Inputs>) => Result]
): RemoteData<MapRemoteDataListToErrors<Inputs>[number], Result> {
// eslint-disable-next-line no-restricted-syntax
const inputs: Inputs = args.slice(0, args.length - 1) as never

if (inputs.length === 0) {
// eslint-disable-next-line no-restricted-syntax
const project = args[args.length - 1] as () => Result
return success(project())
}

const values: unknown[] = []
for (const input of inputs) {
// eslint-disable-next-line no-restricted-syntax
if (input.kind === 'RemotePending' || input.kind === 'RemoteFailure') return input as never
values.push(input.value)
}
// eslint-disable-next-line no-restricted-syntax
const project = args[args.length - 1] as (...args: readonly unknown[]) => Result
return success(project(...values))
}
1 change: 1 addition & 0 deletions packages/remote/src/remote-property/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { RemoteProperty, RemotePropertyError, RemotePropertyValue, combine } from './remote-property'
25 changes: 25 additions & 0 deletions packages/remote/src/remote-property/remote-property.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Property, combine as combineProperty } from '@frp-ts/core'
import { RemoteData, RemoteFailure, RemoteSuccess, combine as combineRemoteData } from '../remote-data/remote-data'

export interface RemoteProperty<Error, Value> extends Property<RemoteData<Error, Value>> {}

export type RemotePropertyValue<Target> = Target extends Property<RemoteSuccess<infer Value>> ? Value : never
export type RemotePropertyError<Target> = Target extends Property<RemoteFailure<infer Error>> ? Error : never

export type MapRemotePropertiesToValues<Inputs extends readonly RemoteProperty<unknown, unknown>[]> = {
readonly [Index in keyof Inputs]: RemotePropertyValue<Inputs[Index]>
}
export type MapRemotePropertiesToErrors<Inputs extends readonly RemoteProperty<unknown, unknown>[]> = {
readonly [Index in keyof Inputs]: RemotePropertyError<Inputs[Index]>
}

export function combine<Inputs extends readonly RemoteProperty<unknown, unknown>[], Result>(
...args: [...Inputs, (...values: MapRemotePropertiesToValues<Inputs>) => Result]
): RemoteProperty<MapRemotePropertiesToErrors<Inputs>[number], Result> {
// eslint-disable-next-line no-restricted-syntax
const inputs: Inputs = args.slice(0, args.length - 1) as never
// eslint-disable-next-line no-restricted-syntax
const project = args[args.length - 1] as (...values: readonly unknown[]) => Result
// eslint-disable-next-line no-restricted-syntax
return combineProperty(...inputs, (...values) => combineRemoteData(...values, project)) as never
}
22 changes: 22 additions & 0 deletions packages/remote/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"module": "CommonJS",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": ["."],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
10 changes: 10 additions & 0 deletions packages/remote/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"declaration": true,
"types": []
},
"include": ["**/*.ts"],
"exclude": ["**/*.spec.ts"]
}
9 changes: 9 additions & 0 deletions packages/remote/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
}