Skip to content

Commit

Permalink
Fix subscribeAll not calling with different reference, causing Reac…
Browse files Browse the repository at this point in the history
…t to skip re-render
  • Loading branch information
somebody1234 committed Nov 26, 2024
1 parent e2ee4a5 commit 0165dda
Show file tree
Hide file tree
Showing 27 changed files with 31 additions and 85 deletions.
61 changes: 5 additions & 56 deletions app/common/src/utilities/data/object.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
/** @file Functions related to manipulating objects. */

// ===============
// === Mutable ===
// ===============

/** Remove the `readonly` modifier from all fields in a type. */
export type Mutable<T> = {
-readonly [K in keyof T]: T[K]
}

// =============
// === merge ===
// =============

/** Prevents generic parameter inference by hiding the type parameter behind a conditional type. */
type NoInfer<T> = [T][T extends T ? 0 : never]

Expand All @@ -35,28 +27,16 @@ export function merger<T extends object>(update: Partial<NoInfer<T>>): (object:
return object => merge(object, update)
}

// ================
// === readonly ===
// ================

/** Makes all properties readonly at the type level. They are still mutable at the runtime level. */
export function readonly<T extends object>(object: T): Readonly<T> {
return object
}

// =====================
// === unsafeMutable ===
// =====================

/** Removes the readonly modifier from all properties on the object. UNSAFE. */
export function unsafeMutable<T extends object>(object: T): { -readonly [K in keyof T]: T[K] } {
return object
}

// =====================
// === unsafeEntries ===
// =====================

/**
* Return the entries of an object. UNSAFE only when it is possible for an object to have
* extra keys.
Expand All @@ -77,10 +57,6 @@ export function unsafeEntries<T extends object>(
return Object.entries(object)
}

// =============================
// === unsafeRemoveUndefined ===
// =============================

/** A the object with `undefined` unsafely removed from the value types of all of its keys. */
export function unsafeRemoveUndefined<T extends object>(
object: T,
Expand All @@ -89,10 +65,6 @@ export function unsafeRemoveUndefined<T extends object>(
return object as never
}

// ==================
// === mapEntries ===
// ==================

/**
* Return the entries of an object. UNSAFE only when it is possible for an object to have
* extra keys.
Expand All @@ -111,28 +83,16 @@ export function mapEntries<K extends PropertyKey, V, W>(
)
}

// ================
// === asObject ===
// ================

/** Either return the object unchanged, if the input was an object, or `null`. */
export function asObject(value: unknown): object | null {
return typeof value === 'object' && value != null ? value : null
}

// =============================
// === singletonObjectOrNull ===
// =============================

/** Either return a singleton object, if the input was an object, or an empty array. */
export function singletonObjectOrNull(value: unknown): [] | [object] {
return typeof value === 'object' && value != null ? [value] : []
}

// ============
// === omit ===
// ============

/** UNSAFE when `Ks` contains strings that are not in the runtime array. */
export function omit<T, Ks extends readonly [string & keyof T, ...(string & keyof T)[]]>(
object: T,
Expand All @@ -145,10 +105,6 @@ export function omit<T, Ks extends readonly [string & keyof T, ...(string & keyo
) as Omit<T, Ks[number]>
}

// ============
// === pick ===
// ============

/** UNSAFE when `Ks` contains strings that are not in the runtime array. */
export function pick<T, Ks extends readonly [string & keyof T, ...(string & keyof T)[]]>(
object: T,
Expand All @@ -161,26 +117,14 @@ export function pick<T, Ks extends readonly [string & keyof T, ...(string & keyo
) as Pick<T, Ks[number]>
}

// ===================
// === ExtractKeys ===
// ===================

/** Filter a type `T` to include only the properties extending the given type `U`. */
export type ExtractKeys<T, U> = {
[K in keyof T]: T[K] extends U ? K : never
}[keyof T]

// ================
// === MethodOf ===
// ================

/** An instance method of the given type. */
export type MethodOf<T> = (this: T, ...args: never) => unknown

// ===================
// === useObjectId ===
// ===================

/** Composable providing support for managing object identities. */
export function useObjectId() {
let lastId = 0
Expand All @@ -197,3 +141,8 @@ export function useObjectId() {
}
return { objectId }
}

/** Create an object given its prototype. */
export function createObject<T extends object>(parent: T): T {
return Object.create(parent)
}
2 changes: 1 addition & 1 deletion app/gui/e2e/dashboard/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import type * as remoteBackend from '#/services/RemoteBackend'
import * as remoteBackendPaths from '#/services/remoteBackendPaths'

import * as dateTime from '#/utilities/dateTime'
import * as object from '#/utilities/object'
import * as permissions from '#/utilities/permissions'
import * as object from 'enso-common/src/utilities/data/object'
import * as uniqueString from 'enso-common/src/utilities/uniqueString'

import * as actions from './actions'
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ import RemoteBackend from '#/services/RemoteBackend'
import { FeatureFlagsProvider } from '#/providers/FeatureFlagsProvider'
import * as appBaseUrl from '#/utilities/appBaseUrl'
import * as eventModule from '#/utilities/event'
import * as object from '#/utilities/object'
import { Path } from '#/utilities/path'
import { STATIC_QUERY_OPTIONS } from '#/utilities/reactQuery'
import * as object from 'enso-common/src/utilities/data/object'

import {
useAcceptedPrivacyPolicyVersionState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import type { CheckboxGroupProps as AriaCheckboxGroupProps } from '#/components/aria'
import { CheckboxGroup as AriaCheckboxGroup, mergeProps } from '#/components/aria'
import { mergeRefs } from '#/utilities/mergeRefs'
import { omit } from '#/utilities/object'
import { forwardRef } from '#/utilities/react'
import type { VariantProps } from '#/utilities/tailwindVariants'
import { tv } from '#/utilities/tailwindVariants'
import { omit } from 'enso-common/src/utilities/data/object'
import type { CSSProperties, ForwardedRef, ReactElement } from 'react'
import type { FieldVariantProps } from '../Form'
import { Form, type FieldPath, type FieldProps, type FieldStateProps, type TSchema } from '../Form'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import * as aria from '#/components/aria'
import * as mergeRefs from '#/utilities/mergeRefs'
import * as twv from '#/utilities/tailwindVariants'

import { omit } from '#/utilities/object'
import { forwardRef } from '#/utilities/react'
import { omit } from 'enso-common/src/utilities/data/object'
import type { FieldVariantProps } from '../Form'
import * as formComponent from '../Form'
import * as radioGroupContext from './RadioGroupContext'
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/components/JSONSchemaInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { useBackendQuery } from '#/hooks/backendHooks'
import { useRemoteBackend } from '#/providers/BackendProvider'
import { useText } from '#/providers/TextProvider'
import { constantValueOfSchema, getSchemaName, lookupDef } from '#/utilities/jsonSchema'
import { asObject, singletonObjectOrNull } from '#/utilities/object'
import { twMerge } from '#/utilities/tailwindMerge'
import { asObject, singletonObjectOrNull } from 'enso-common/src/utilities/data/object'
import { twJoin } from 'tailwind-merge'

// =======================
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/components/dashboard/AssetRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ import { download } from '#/utilities/download'
import * as drag from '#/utilities/drag'
import * as eventModule from '#/utilities/event'
import * as indent from '#/utilities/indent'
import * as object from '#/utilities/object'
import * as permissions from '#/utilities/permissions'
import * as set from '#/utilities/set'
import * as tailwindMerge from '#/utilities/tailwindMerge'
import Visibility from '#/utilities/Visibility'
import * as object from 'enso-common/src/utilities/data/object'
import invariant from 'tiny-invariant'
import { IndefiniteSpinner } from '../Spinner'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import type * as backendModule from '#/services/Backend'
import { useSetIsAssetPanelTemporarilyOpen } from '#/layouts/AssetPanel'
import * as eventModule from '#/utilities/event'
import * as indent from '#/utilities/indent'
import * as object from '#/utilities/object'
import * as tailwindMerge from '#/utilities/tailwindMerge'
import * as object from 'enso-common/src/utilities/data/object'

// ====================
// === DatalinkName ===
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ import * as backendModule from '#/services/Backend'
import { useStore } from '#/hooks/storeHooks'
import * as eventModule from '#/utilities/event'
import * as indent from '#/utilities/indent'
import * as object from '#/utilities/object'
import * as string from '#/utilities/string'
import * as tailwindMerge from '#/utilities/tailwindMerge'
import * as validation from '#/utilities/validation'
import * as object from 'enso-common/src/utilities/data/object'

// =====================
// === DirectoryName ===
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import * as backendModule from '#/services/Backend'
import * as eventModule from '#/utilities/event'
import * as fileIcon from '#/utilities/fileIcon'
import * as indent from '#/utilities/indent'
import * as object from '#/utilities/object'
import * as string from '#/utilities/string'
import * as tailwindMerge from '#/utilities/tailwindMerge'
import * as object from 'enso-common/src/utilities/data/object'

// ================
// === FileName ===
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/components/dashboard/Permission.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import type Backend from '#/services/Backend'
import * as backendModule from '#/services/Backend'

import { Text } from '#/components/AriaComponents'
import * as object from '#/utilities/object'
import * as object from 'enso-common/src/utilities/data/object'

// =================
// === Constants ===
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ import * as backendModule from '#/services/Backend'

import * as eventModule from '#/utilities/event'
import * as indent from '#/utilities/indent'
import * as object from '#/utilities/object'
import * as permissions from '#/utilities/permissions'
import * as string from '#/utilities/string'
import * as tailwindMerge from '#/utilities/tailwindMerge'
import * as validation from '#/utilities/validation'
import { isOnMacOS } from 'enso-common/src/detect'
import * as object from 'enso-common/src/utilities/data/object'

// ===================
// === ProjectName ===
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import type * as backendModule from '#/services/Backend'

import * as eventModule from '#/utilities/event'
import * as indent from '#/utilities/indent'
import * as object from '#/utilities/object'
import * as tailwindMerge from '#/utilities/tailwindMerge'
import * as object from 'enso-common/src/utilities/data/object'

// =====================
// === ConnectorName ===
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/hooks/measureHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
*/
import { frame } from 'framer-motion'

import { unsafeMutable } from 'enso-common/src/utilities/data/object'
import { startTransition, useEffect, useRef, useState } from 'react'
import { unsafeMutable } from '../utilities/object'
import { useDebouncedCallback } from './debounceCallbackHooks'
import { useEventCallback } from './eventCallbackHooks'
import { useUnmount } from './unmountHooks'
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/layouts/AssetContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ import { useNewProject, useUploadFileWithToastMutation } from '#/hooks/backendHo
import { usePasteData } from '#/providers/DriveProvider'
import { normalizePath } from '#/utilities/fileInfo'
import { mapNonNullish } from '#/utilities/nullable'
import * as object from '#/utilities/object'
import * as permissions from '#/utilities/permissions'
import * as object from 'enso-common/src/utilities/data/object'
import { useSetAssetPanelProps, useSetIsAssetPanelTemporarilyOpen } from './AssetPanel'

// ========================
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/layouts/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import Twemoji from '#/components/Twemoji'
import { useSyncRef } from '#/hooks/syncRefHooks'
import * as dateTime from '#/utilities/dateTime'
import * as newtype from '#/utilities/newtype'
import * as object from '#/utilities/object'
import * as tailwindMerge from '#/utilities/tailwindMerge'
import * as object from 'enso-common/src/utilities/data/object'

// ================
// === Newtypes ===
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import CaptureKeyboardShortcutModal from '#/modals/CaptureKeyboardShortcutModal'
import ConfirmDeleteModal from '#/modals/ConfirmDeleteModal'
import { useInputBindings } from '#/providers/InputBindingsProvider'
import { useText } from '#/providers/TextProvider'
import { unsafeEntries } from '#/utilities/object'
import { unsafeEntries } from 'enso-common/src/utilities/data/object'

// ========================================
// === KeyboardShortcutsSettingsSection ===
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/layouts/Settings/data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import {
import type LocalBackend from '#/services/LocalBackend'
import type RemoteBackend from '#/services/RemoteBackend'
import { normalizePath } from '#/utilities/fileInfo'
import { pick, unsafeEntries } from '#/utilities/object'
import { PASSWORD_REGEX } from '#/utilities/validation'
import { pick, unsafeEntries } from 'enso-common/src/utilities/data/object'
import ActivityLogSettingsSection from './ActivityLogSettingsSection'
import DeleteUserAccountSettingsSection from './DeleteUserAccountSettingsSection'
import KeyboardShortcutsSettingsSection from './KeyboardShortcutsSettingsSection'
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/modals/DuplicateAssetsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import Modal from '#/components/Modal'
import * as backendModule from '#/services/Backend'

import * as fileInfo from '#/utilities/fileInfo'
import * as object from '#/utilities/object'
import { useMutation } from '@tanstack/react-query'
import * as object from 'enso-common/src/utilities/data/object'

// =============
// === Types ===
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/providers/FeatureFlagsProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useEffect, type ReactNode } from 'react'
import { createStore, useStore } from 'zustand'

import { useMount } from '#/hooks/mountHooks'
import { unsafeEntries } from '#/utilities/object'
import { unsafeEntries } from 'enso-common/src/utilities/data/object'
import { useFeatureFlags as useFeatureFlagsInternal } from './FeatureFlagsProvider/featureFlagsLocalStorage'
import { useLocalStorage } from './LocalStorageProvider'
export { FEATURE_FLAGS_SCHEMA } from './FeatureFlagsProvider/featureFlagsLocalStorage'
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/providers/TextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as React from 'react'

import * as text from 'enso-common/src/text'

import * as object from '#/utilities/object'
import * as object from 'enso-common/src/utilities/data/object'

// ===================
// === TextContext ===
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/services/RemoteBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import * as remoteBackendPaths from '#/services/remoteBackendPaths'

import * as download from '#/utilities/download'
import type HttpClient from '#/utilities/HttpClient'
import * as object from '#/utilities/object'
import * as object from 'enso-common/src/utilities/data/object'

// =================
// === Constants ===
Expand Down
4 changes: 2 additions & 2 deletions app/gui/src/dashboard/utilities/LocalStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type * as z from 'zod'
import { PRODUCT_NAME } from 'enso-common'
import { IS_DEV_MODE } from 'enso-common/src/detect'

import { unsafeEntries, unsafeKeys } from '#/utilities/object'
import { createObject, unsafeEntries, unsafeKeys } from 'enso-common/src/utilities/data/object'

const KEY_DEFINITION_STACK_TRACES = new Map<string, string>()

Expand Down Expand Up @@ -140,7 +140,7 @@ export class LocalStorage {
/** Add an event listener to all keys. */
subscribeAll(callback: (value: Record<string, unknown>) => void) {
const onChange = () => {
callback(this.values)
callback(createObject(this.values))
}
onChange()

Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/dashboard/utilities/Navigator2D.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type * as React from 'react'
import * as detect from 'enso-common/src/detect'

import * as eventModule from '#/utilities/event'
import * as object from '#/utilities/object'
import * as object from 'enso-common/src/utilities/data/object'

// =================
// === Constants ===
Expand Down
Loading

0 comments on commit 0165dda

Please sign in to comment.