Skip to content

Commit

Permalink
Remove custom Promise polyfill
Browse files Browse the repository at this point in the history
  • Loading branch information
timowestnosto committed Jan 22, 2024
1 parent 8582a95 commit edd4d05
Show file tree
Hide file tree
Showing 7 changed files with 11 additions and 155 deletions.
3 changes: 1 addition & 2 deletions src/api/client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { AnyPromise } from "../utils/promise"
import { InputSearchQueryWithFields } from "./search"
import { SearchResult } from "./search/generated"

Expand Down Expand Up @@ -76,7 +75,7 @@ export interface NostoClient {
* @category Core
*/
export function getNostoClient(): PromiseLike<NostoClient> {
return new AnyPromise((resolve, reject) => {
return new Promise((resolve, reject) => {
if ("nostojs" in window && typeof window.nostojs === "function") {
window.nostojs((api: NostoClient) => {
resolve(api)
Expand Down
5 changes: 2 additions & 3 deletions src/liquid.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { DefaultState } from "./utils/state"
import { AnyPromise } from "./utils/promise"
import { Liquid } from "liquidjs"

/**
Expand All @@ -24,7 +23,7 @@ export function fromLiquidTemplate<State extends object = DefaultState>(
return (container, state) => {
container.innerHTML = instance.parseAndRenderSync(template, state)

return AnyPromise.resolve(undefined)
return Promise.resolve(undefined)
}
}

Expand All @@ -40,7 +39,7 @@ export function fromRemoteLiquidTemplate<State extends object = DefaultState>(
url: string
): (container: HTMLElement, state: State) => PromiseLike<void> {
return (container, state) => {
return new AnyPromise((resolve, reject) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open("GET", url)
xhr.onload = () => {
Expand Down
5 changes: 2 additions & 3 deletions src/mustache.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { AnyPromise } from "./utils/promise"
import { DefaultState } from "./utils/state"
import Mustache from "mustache"

Expand Down Expand Up @@ -27,7 +26,7 @@ export function fromMustacheTemplate(template: string) {
},
})

return AnyPromise.resolve(undefined)
return Promise.resolve(undefined)
}
}

Expand All @@ -43,7 +42,7 @@ export function fromRemoteMustacheTemplate<State extends object = DefaultState>(
url: string
): (container: HTMLElement, state: State) => PromiseLike<void> {
return (container, state) => {
return new AnyPromise((resolve, reject) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open("GET", url)
xhr.onload = () => {
Expand Down
4 changes: 1 addition & 3 deletions src/utils/dropdown.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { AnyPromise } from "./promise"

type OnClickBindings<State> = {
[key: string]: (obj: {
data: string | undefined
Expand Down Expand Up @@ -228,7 +226,7 @@ export function createDropdown<State>(
container.innerHTML = ""
}

AnyPromise.resolve(initialState)
Promise.resolve(initialState)
.then(state => render(container, state as State))
.then(() => {
// Without setTimeout React does not have committed DOM changes yet, so we don't have the correct elements.
Expand Down
4 changes: 1 addition & 3 deletions src/utils/limiter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { AnyPromise } from "./promise"

type Callback<T> = () => PromiseLike<T>

interface Event<T> {
Expand All @@ -22,7 +20,7 @@ export function createLimiter<T = void>(
let lastEvent: Event<T> | undefined

function limited(getPromise?: Callback<T>): PromiseLike<T> {
return new AnyPromise<T>((resolve, reject) => {
return new Promise<T>((resolve, reject) => {
currentNumber += 1
const event = {
getPromise,
Expand Down
139 changes: 1 addition & 138 deletions src/utils/promise.ts
Original file line number Diff line number Diff line change
@@ -1,148 +1,11 @@
export class SimplePromise<T> implements PromiseLike<T> {
private status: string
private value: T
private onFulfilledCallbacks: Array<(value: T) => void>
private onRejectedCallbacks: Array<(value: unknown) => void>

constructor(
handler: (
resolve: (value: T) => void,
reject: (reason?: unknown) => void
) => void
) {
this.value = null as T
this.status = "pending"
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []

const resolve = (value: T) => {
if (this.status === "pending") {
this.status = "fulfilled"
this.value = value
this.onFulfilledCallbacks.forEach(fn => fn(value))
}
}

const reject = (value: unknown) => {
if (this.status === "pending") {
this.status = "rejected"
this.value = value as T
this.onRejectedCallbacks.forEach(fn => fn(value))
}
}

try {
handler(resolve, reject)
} catch (err: unknown) {
reject(err)
}
}

then<TResult1 = T, TResult2 = never>(
onfulfilled?:
| ((value: T) => TResult1 | PromiseLike<TResult1>)
| null
| undefined,
onrejected?:
| ((reason: unknown) => TResult2 | PromiseLike<TResult2>)
| undefined
| null
): PromiseLike<TResult1 | TResult2> {
return new SimplePromise((resolve, reject) => {
if (this.status === "pending") {
this.onFulfilledCallbacks.push(() => {
try {
const fulfilledFromLastPromise = onfulfilled?.(
this.value
)
if (
fulfilledFromLastPromise &&
typeof fulfilledFromLastPromise === "object" &&
"then" in fulfilledFromLastPromise
) {
fulfilledFromLastPromise.then(resolve, reject)
} else {
resolve(fulfilledFromLastPromise as TResult1)
}
} catch (err) {
reject(err)
}
})
this.onRejectedCallbacks.push(() => {
try {
const rejectedFromLastPromise = onrejected?.(this.value)
if (
rejectedFromLastPromise &&
typeof rejectedFromLastPromise === "object" &&
"then" in rejectedFromLastPromise
) {
rejectedFromLastPromise.then(resolve, reject)
} else {
reject(rejectedFromLastPromise)
}
} catch (err) {
reject(err)
}
})
}

if (this.status === "fulfilled") {
try {
const fulfilledFromLastPromise = onfulfilled?.(this.value)
if (
fulfilledFromLastPromise &&
typeof fulfilledFromLastPromise === "object" &&
"then" in fulfilledFromLastPromise
) {
fulfilledFromLastPromise.then(resolve, reject)
} else {
resolve(fulfilledFromLastPromise as TResult1)
}
} catch (err) {
reject(err)
}
}

if (this.status === "rejected") {
try {
const rejectedFromLastPromise = onrejected?.(this.value)
if (
rejectedFromLastPromise &&
typeof rejectedFromLastPromise === "object" &&
"then" in rejectedFromLastPromise
) {
rejectedFromLastPromise.then(resolve, reject)
} else {
reject(rejectedFromLastPromise)
}
} catch (err) {
reject(err)
}
}
})
}

static resolve<T>(value: T | PromiseLike<T>): PromiseLike<T> {
return new SimplePromise<T>((resolve, reject) => {
if (value && typeof value === "object" && "then" in value) {
value.then(resolve, reject)
} else {
resolve(value)
}
})
}
}

export const AnyPromise = "Promise" in window ? window.Promise : SimplePromise

export type Cancellable<T> = { promise: PromiseLike<T>; cancel: () => void }

export class CancellableError extends Error {}

export function makeCancellable<T>(promise: PromiseLike<T>): Cancellable<T> {
let hasCanceled_ = false

const wrappedPromise = new AnyPromise<T>((resolve, reject) => {
const wrappedPromise = new Promise<T>((resolve, reject) => {
promise.then(
val => {
hasCanceled_
Expand Down
6 changes: 3 additions & 3 deletions src/utils/state.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { InputSearchQuery, SearchResult } from "../api/search/generated"
import { AutocompleteConfig } from "../config"
import { History } from "./history"
import { AnyPromise, Cancellable, makeCancellable } from "./promise"
import { Cancellable, makeCancellable } from "./promise"
import { search } from "../search"

/**
Expand Down Expand Up @@ -59,7 +59,7 @@ export const getStateActions = <State>({
}

const getHistoryState = (query: string) => {
return AnyPromise.resolve({
return Promise.resolve({
query: {
query,
},
Expand Down Expand Up @@ -89,7 +89,7 @@ export const getStateActions = <State>({
e => {
throw e
}
) ?? AnyPromise.resolve({}).then(s => s as State)
) ?? Promise.resolve({}).then(s => s as State)
)
},
addHistoryItem: (item: string) => {
Expand Down

0 comments on commit edd4d05

Please sign in to comment.