pp-share (Global Shared Reactivity)

pphp.share creates a global, reactive store that lives in the internal __shared namespace. Any component can read and update it. Unlike state, a share is overridable at the app level, and there’s only one instance per key. Use pphp.getShared(key) to access a shared value anywhere (without re-declaring), and you can observe changes with pphp.effect.

Single source of truth: A share has exactly one instance per key in __shared. Setting it anywhere overrides the value for the whole app.

API

public share<T>(
  key: string,
  initial?: T
): [(() => T) & { value: T }, (v: T | ((p: T) => T)) => void] {}

public getShared<T = any>(key: string): T &
  ((...args: any[]) => T) & {
    set: (value: T | ((prev: T) => T)) => void;
  } {}

public clearShare(key?: string): void {}

Parameters & Return Types

Function Param Type Default Description
share<T> key string Unique key for the shared value. Must be a non-empty string and not reserved.
initial T Initial value when the shared key is first created.
Returns A tuple [getter, setter] where:
  • getter(): T also exposes getter.value.
  • setter(next: T | (prev: T) => T) updates globally.
getShared<T> key string Key of the shared value to read/update without re-declaring.
Returns A callable reactive proxy that behaves like a getter function and object:
  • Call it: user() → returns T.
  • Update: user.set(next) or user.set(prev => ...).
  • Property access is reactive: user.name, user.settings.theme, etc.
clearShare key? string Delete one shared key (clearShare('user')) or all (clearShare()).

Behavior & Guarantees

  • Global & overridable: setting a share anywhere updates it everywhere.
  • Single instance: a share lives in __shared.<key>.
  • Fast-path reuse: calling pphp.share again with the same key returns the same getter/setter.
  • Conflict warning: if a local state uses the same key in scope, a console warning is logged; the shared setter takes priority via the global key.
  • Reactive proxy from getShared: the returned value is callable and property-reactive, with a built-in .set.
  • Late binding: if a share isn’t ready yet, getShared performs short retry checks and updates dependencies once it appears.
Global override: Using the same key across app and components will override the value everywhere. Choose explicit, descriptive keys to avoid collisions.

Use Cases

  • Auth/session info shared across header, sidebar, and protected pages.
  • Theme or layout toggles (dark mode, compact mode, RTL, etc.).
  • Cart/checkout data reflected in multiple UI regions.
  • Global notifications/snackbars and unread counters.

Basic Usage with share

<script>
// Declare (or reuse) a global counter
const [counter, setCounter] = pphp.share(0);

// Read in JS
console.log(counter());       // 0
console.log(counter.value);   // 0

// Update globally
setCounter(p => p + 1);
</script>

<!-- In any template -->
<p>Counter: {{ counter }}</p>  <!-- mustache works with the getter -->

<button class="btn btn-primary btn-sm" onclick="increment">+1</button>
<script>
function increment() {
  setCounter(c => c + 1);
}
</script>

Access Anywhere with getShared

<script>
// No need to re-declare share; read/update from anywhere:
const user = pphp.getShared('user'); // callable reactive proxy

// Read:
console.log(user());       // full object or primitive
console.log(user.name);    // reactive property access

// Update:
user.set(prev => ({ ...prev, name: 'Ada' }));
// or replace entirely:
user.set({ name: 'Grace', role: 'admin' });
</script>

<p>Hello, {{ user.name || 'Guest' }}</p>

Watching Changes with pphp.effect

<script>
// Observe updates on a shared key
const auth = pphp.getShared('auth');

pphp.effect(() => {
  console.log('Auth changed:', auth()); // or auth.user, auth.token, etc.
}, ['auth']); // dependency can be the shared key string
</script>

Overriding a Shared Value (Global)

<script>
// Component A
const [theme, setTheme] = pphp.share({ mode: 'light' });

// Component B (later, anywhere):
const themeProxy = pphp.getShared('theme');

// This will override app-wide:
themeProxy.set({ mode: 'dark' }); // all places now read dark
</script>

Clearing Shared State

<script>
// Remove one shared key:
pphp.clearShare('user');

// Or wipe all shares (careful!):
pphp.clearShare();
</script>

Advanced: Shared Objects with Methods

You can store objects and mutate them via methods. Property access remains reactive, and .set can replace or update the whole object.

<script>
const [profile, setProfile] = pphp.share({
  name: '',
  age: 0,
  set(data) {
    this.name = data.name ?? this.name;
    this.age  = data.age  ?? this.age;
  },
  reset() {
    this.name = '';
    this.age  = 0;
  }
});

// Elsewhere:
const sharedProfile = pphp.getShared('profile');
sharedProfile.set(p => ({ ...p, name: 'Jefferson' })); // updater
profile().set({ age: 29 }); // method on the object
</script>

<p>Name: {{ profile.name }} ({{ profile.age }})</p>
Tips:
  • Use pphp.effect(() => {...}, ['yourKey']) to react to shared changes.
  • Reserved words are blocked for safety; choose descriptive keys.
  • getShared gracefully binds even if the share is created later.