8000 Proposal: useObjectStore Hook · Issue #16 · raycast/utils · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Proposal: useObjectStore Hook #16
Open
@SKaplanOfficial

Description

@SKaplanOfficial

Summary: A hook to simplify the creation and management of object dictionaries in LocalStorage, with a simple interface for CRUD operations. This would be useful for storing objects that populate List and Grid views, for example.

Details: This hook would create a LocalStorage entry containing a dictionary of objects as a JSON string, and it would provide easy access to methods for accessing, removing, and updating objects, as well as for performing object key migrations and batch-adding of new keys. A cached option could be provided.

Quite a few extensions store objects in this way and would benefit from a dedicated implementation, especially one that supports future development by providing methods for migrations (since the need/want to rename or delete keys is often unforeseen). Moreover, a standard implementation would allow additional features going forward, e.g. an option to use a JSON file in the extension's support directory rather than in LocalStorage, with minimal changes in extensions' code.

I'd be happy to work on this if there's support for it.

Proposed Interface:

interface LocalObjectStore<T> {
  allObjects: () => T[];

  // Add an object to the store, return the UUID for the object
  addObject: (object: T) => string;
  
  removeObject: (object: T) => void;
  getObject: (id: string) => T | undefined;
  setObject: (id: string, object: T) => void;
  updateObject(id: string, updateFunction: (oldObject: T) => T): void;
  removeObject: (id: string) => void;
  clear: () => void;

  // Rename a key within each obje
7505
ct in the store, preserving the value
  renameKey: (oldKey: string, newKey: string) => void;

  // Add a key to each object in the store, using the provided function to generate the value
  addKey: (key: string, valueFunction: (object: T) => any) => void;

  // Delete a key from each object in the store
  deleteKey: (key: string) => void;
}

Example:

import { Action, ActionPanel, Grid } from "@raycast/api";
import { useObjectStore } from '@raycast/utils';

interface EmojiItem {
  name: string;
  emoji: string;
  description: string;
}

export default function Command() {

// Creates the store if it doesn't exist, or returns the existing store
const emojiStore = useObjectStore<EmojiItem>('emoji-items');

useEffect(() => {
  emojiStore.addObject({
    name: 'Smile',
    emoji: '😀',
    description: 'A happy face',
  });
}, []);

// Loads items once upon first render, updates when items are added/removed/modified
const emojiItems = emojiStore.allObjects();

return(
  <Grid>
    {emojiItems.map((item) => (
      <Grid.Item
        key={item.id} // Auto-generated UUID
        title={item.name}
        subtitle={item.description}
        content={item.emoji}
        actions={
          <ActionPanel>
            <Action
              title="Remove"
              onAction={() => emojiStore.removeObject(item.id)}
            />
          </ActionPanel>
        }
      />
    ))}
  </Grid>
);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0