Skip to content

Commit

Permalink
JoinAsyncOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
guillemcordoba committed Nov 14, 2023
1 parent 075445f commit 982521d
Show file tree
Hide file tree
Showing 15 changed files with 474 additions and 55 deletions.
3 changes: 1 addition & 2 deletions packages/elements/custom-elements.json
Original file line number Diff line number Diff line change
Expand Up @@ -842,8 +842,7 @@
"name": "defaultValue",
"type": {
"text": "Date | number | string | undefined"
},
"default": "new Date()"
}
},
{
"kind": "field",
Expand Down
1 change: 1 addition & 0 deletions packages/elements/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
<sl-datetime-input
label="hi"
required
.defaultValue=${new Date()}
name="timestamp"
></sl-datetime-input>
<sl-input
Expand Down
2 changes: 1 addition & 1 deletion packages/elements/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@holochain-open-dev/elements",
"version": "0.8.2",
"version": "0.8.3",
"description": "Common utilities and elements to build Holochain web applications",
"author": "[email protected]",
"main": "dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/elements/src/date-utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export function formatDateForInput(date: Date): string {
return `${date.getFullYear()}-${(date.getMonth() + 1)
.toString()
.padStart(2, "0")}-${date.getDate()}T${date
.padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}T${date
.getHours()
.toString()
.padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}`;
Expand Down
17 changes: 10 additions & 7 deletions packages/elements/src/elements/sl-datetime-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class SlDatetimeInput extends LitElement implements FormField {
name: string | undefined;

@property()
defaultValue: Date | number | string | undefined = new Date();
defaultValue: Date | number | string | undefined;

@property({ type: Boolean, attribute: "required" })
required = false;
Expand Down Expand Up @@ -95,14 +95,17 @@ export class SlDatetimeInput extends LitElement implements FormField {
}

get value(): string | undefined {
const dateValue = this.dateField.value;
const timeValue = this.timeField.value;
try {
const dateValue = this.dateField.value;
const timeValue = this.timeField.value;

if (!dateValue || !timeValue) return "";
if (!dateValue || !timeValue) return "";
const date = new Date(`${dateValue}T${timeValue}`);

const date = new Date(`${dateValue}T${timeValue}`);

return date.toISOString();
return date.toISOString();
} catch (_e) {
return undefined;
}
}

render() {
Expand Down
2 changes: 1 addition & 1 deletion packages/stores/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@holochain-open-dev/stores",
"version": "0.7.12",
"version": "0.7.15",
"description": "Re-export of svelte/store, with additional utilities to build reusable holochain-open-dev modules",
"author": "[email protected]",
"main": "dist/index.js",
Expand Down
92 changes: 69 additions & 23 deletions packages/stores/src/async-derived.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,45 @@ export function asyncDerived<T, S extends AsyncReadable<any>>(
});
}

/**
* Defines the behavior of the joining of the `AsyncReadables`
*/
export interface JoinAsyncOptions {
/**
* 'bubbles': the first error encountered in the collection of stores is going to be automatically returned
* 'filter_out': all errors encountered in the collection of stores are going to be filtered out, returning only those stores that completed successfully
*/
errors?: "filter_out" | "bubble";
/**
* 'bubbles': the first pending status encountered in the collection of stores is going to be automatically returned
* 'filter_out': all pending status encountered in the collection of stores are going to be filtered out, returning only those stores that completed successfully
*/
pendings?: "filter_out" | "bubble";
}

/**
* Joins an array of `AsyncReadables` into a single `AsyncReadable` of the array of values
*/
export function joinAsync<T>(stores: [AsyncReadable<T>]): AsyncReadable<[T]>;
export function joinAsync<T>(
stores: [AsyncReadable<T>],
joinOptions?: JoinAsyncOptions
): AsyncReadable<[T]>;
export function joinAsync<T, U>(
stores: [AsyncReadable<T>, AsyncReadable<U>]
stores: [AsyncReadable<T>, AsyncReadable<U>],
joinOptions?: JoinAsyncOptions
): AsyncReadable<[T, U]>;
export function joinAsync<T, U, V>(
stores: [AsyncReadable<T>, AsyncReadable<U>, AsyncReadable<V>]
stores: [AsyncReadable<T>, AsyncReadable<U>, AsyncReadable<V>],
joinOptions?: JoinAsyncOptions
): AsyncReadable<[T, U, V]>;
export function joinAsync<T, U, V, W>(
stores: [
AsyncReadable<T>,
AsyncReadable<U>,
AsyncReadable<V>,
AsyncReadable<W>
]
],
joinOptions?: JoinAsyncOptions
): AsyncReadable<[T, U, V, W]>;
export function joinAsync<T, U, V, W, X>(
stores: [
Expand All @@ -83,7 +105,8 @@ export function joinAsync<T, U, V, W, X>(
AsyncReadable<V>,
AsyncReadable<W>,
AsyncReadable<X>
]
],
joinOptions?: JoinAsyncOptions
): AsyncReadable<[T, U, V, W, X]>;
export function joinAsync<T, U, V, W, X, Y>(
stores: [
Expand All @@ -93,7 +116,8 @@ export function joinAsync<T, U, V, W, X, Y>(
AsyncReadable<W>,
AsyncReadable<X>,
AsyncReadable<Y>
]
],
joinOptions?: JoinAsyncOptions
): AsyncReadable<[T, U, V, W, X, Y]>;
export function joinAsync<T, U, V, W, X, Y, Z>(
stores: [
Expand All @@ -104,7 +128,8 @@ export function joinAsync<T, U, V, W, X, Y, Z>(
AsyncReadable<X>,
AsyncReadable<Y>,
AsyncReadable<Z>
]
],
joinOptions?: JoinAsyncOptions
): AsyncReadable<[T, U, V, W, X, Y, Z]>;
export function joinAsync<T, U, V, W, X, Y, Z, A>(
stores: [
Expand All @@ -116,7 +141,8 @@ export function joinAsync<T, U, V, W, X, Y, Z, A>(
AsyncReadable<Y>,
AsyncReadable<Z>,
AsyncReadable<A>
]
],
joinOptions?: JoinAsyncOptions
): AsyncReadable<[T, U, V, W, X, Y, Z, A]>;
export function joinAsync<T, U, V, W, X, Y, Z, A, B>(
stores: [
Expand All @@ -129,7 +155,8 @@ export function joinAsync<T, U, V, W, X, Y, Z, A, B>(
AsyncReadable<Z>,
AsyncReadable<A>,
AsyncReadable<B>
]
],
joinOptions?: JoinAsyncOptions
): AsyncReadable<[T, U, V, W, X, Y, Z, A, B]>;
export function joinAsync<T, U, V, W, X, Y, Z, A, B, C>(
stores: [
Expand All @@ -143,29 +170,48 @@ export function joinAsync<T, U, V, W, X, Y, Z, A, B, C>(
AsyncReadable<A>,
AsyncReadable<B>,
AsyncReadable<C>
]
],
joinOptions?: JoinAsyncOptions
): AsyncReadable<[T, U, V, W, X, Y, Z, A, B, C]>;
export function joinAsync<T>(
stores: Array<AsyncReadable<T>>
stores: Array<AsyncReadable<T>>,
joinOptions?: JoinAsyncOptions
): AsyncReadable<Array<T>>;
export function joinAsync<T>(
stores: Array<AsyncReadable<T>>
stores: Array<AsyncReadable<T>>,
joinOptions?: JoinAsyncOptions
): AsyncReadable<Array<T>> {
let options = {
errors: "bubble",
pendings: "bubble",
};
if (joinOptions) {
options = {
...options,
...joinOptions,
};
}
return derived(stores, (values): AsyncStatus<T[]> => {
const firstError = values.find(
(v) => v && (v as AsyncStatus<any>).status === "error"
);
if (firstError) {
return firstError as AsyncStatus<T[]>;
if (options.errors === "bubble") {
const firstError = values.find(
(v) => v && (v as AsyncStatus<any>).status === "error"
);
if (firstError) {
return firstError as AsyncStatus<T[]>;
}
}
const firstLoading = values.find(
(v) => v && (v as AsyncStatus<any>).status === "pending"
);
if (firstLoading) {
return firstLoading as AsyncStatus<T[]>;
if (options.pendings === "bubble") {
const firstLoading = values.find(
(v) => v && (v as AsyncStatus<any>).status === "pending"
);
if (firstLoading) {
return firstLoading as AsyncStatus<T[]>;
}
}

const v = values.map((v) => (v as any).value as T);
const v = values
.filter((v) => v.status === "complete")
.map((v) => (v as any).value as T);
return {
status: "complete",
value: v,
Expand Down
Loading

0 comments on commit 982521d

Please sign in to comment.