Giter Site home page Giter Site logo

Comments (48)

betula avatar betula commented on June 9, 2024

Working started:
[+] reset
[+] promise

from realar.

betula avatar betula commented on June 9, 2024

Backlog from api-0.6 implementation

  [] trigger should be touchable
  [] value.touchable(initial) <- The ".from" construction not available for values with "initial" dependency requireds
  [] signal.touchable(initial)
  [] v.as.readonly()
  [] flow.resolve
  [] flow as root level exportable factory function
  [] .chan
  [] value.trigger.from
  [] value.trigger.flag.from
  [] .map <- sysnonym for .view (on thinking)
  [] x.group -- x.op -- x.block
    x.block((ctx) => ({  // if returns non undefined
      a: ctx.a,
      b: ctx.a.select()
    })).b.val
  [] v.as.signal(), v.as.trigger.flag()

from realar.

betula avatar betula commented on June 9, 2024

Backlog:
[] Add callback to join, and combine. After It possible to use object config for join with callback
[] .as.trigger
[] .as.value.trigger
[] .as.signal.trigger

[] signal.trigger.resolved
[] value.trigger.resolved

[] test case "should work signal.trigger with configured .pre"

[] signal.trigger.from
[] value.trigger.from

[] Add Loader example to documentation

  // Second example
  const Loader = () => {
    const count = value(0);

    return {
      start: count.updater(v => v + 1),
      stop: count.updater(v => v - 1),
      pending: count.select(v => v > 0)
    }
  }

from realar.

betula avatar betula commented on June 9, 2024

Join brainstorm:

[] Add track|untrack for join with callback

I think better way in that case is removing callback support for current version.
because without callback for combine and join no have any conficts for syntax.
I can use track|untrack for join without callback with no disharmony

--> decision for version 0.6:
  [] remove callback support for join and combine
  [] Add track|untrack for join
    ...disharmony was stay
--> decision number two) The second
  [] rename join to "attach" or "merge"

    Task: The saving consistency of track|untrack for append|attach|join|merge function

    Have a reason for join without tracking for a set of rective values.

      Have a reason join for signals?

value.combine() -> ok
value.join() -> ok

I cant implement signal.combine([], fn and s.join([], fn) because I have not flag for ready all
signals from argument

signal.combine() -> not ok
signal.join() -> not ok

maybe support combine and join only for values now.
For signal I can use merge

const s = signal(0);
s.merge([() => s.val, ...]).val == 0; without callback

Summary:
[] I should implement value.combine([]|{}, fn?), and value(0).combine([] | {}, fn?)
- track|untrack for combine? (I can not support untrack for combine values)

[] No have similar for signal in 0.6 versions.

value.from(() => ({
a: a.val,
b: b.val
}))
value.combine({ a, b }) -> better...
Always tracked, and it used only for values

value(0).combine - have a problem with track|untrack semantic not for 0.6 version.

I should make only value.combine. Aren't It?
Ok. For 0.6 its enough

from realar.

betula avatar betula commented on June 9, 2024

Backlog
[] as.value(dafault_value?)
[] support reactionable for untrack
[] value().get.untrack()

from realar.

betula avatar betula commented on June 9, 2024

Backlog
[] Add default for resolve "Will" type

  const v = value(0).filter().default(0)

from realar.

betula avatar betula commented on June 9, 2024

Backlog:

const r = signal();
const u = signal<number>();

const v = value(0);

v.reset.by(r);

v.update.by(u, (state, up_value, up_value_prev) => {
  return state + (up_value - (up_value_prev || 0));
});

u(10);
r();

And I think to very interesting idea is the convert "reset" function method to signal

const a = value(0);

a.reset.to(() => console.log("reset"));

from realar.

betula avatar betula commented on June 9, 2024

proposal: local

cosnt v = value(0);

v.flow((value) => {
  const ticket = local(() => wait(k));
  if (!ticket.val) return flow.stop();
  return value;
});

v.flow.filter(() => {
  return local(() => wait(k)).val
});

local(expr) // <- bind only first time not necessary bind it every time
                   // if you need bind every time you should use plain function not local expression.
                   // synonim of local(expr, []);
local(expr, [<real value dep>, ...])
local(expr, <refresh symbol or expression>);

// or all combination of that
local(expr, <refresh symbol or expression>, [<real value dep>, ...]);
local(expr, [<real value dep>, ...], <refresh symbol or expression>);

from realar.

betula avatar betula commented on June 9, 2024

proposal: wait

const v = value(0);
const s = signal(0);

// wait.all([v, s]) - it is a ready (trigger)

await wait.all([v, s]).promise
await wait.once([v, s]).promise

wait(v) // similar to signal.trigger.from(v) or v.to.signal.trigger()
const k = signal(0);
const m = value(0);

v.flow.wait(m)
  .flow.wait.all(k, m) // or synonim to .flow.wait.all([k, m]) -- think about
  .flow.wait.race(k, m)
  .to((v) => console.log(v));
const k = signal(0);
const m = value(0);

v.flow.wait(m, (v_val, m_val) => return v_val + m_val)
  .flow.wait.all([k, m], (v_val, [k_val, m_val]) => return v_val + k_val + m_val) // or stop of course (maybe I can get resolve???)
  .flow.wait.race([k, m], (v_val, [k_val, m_val], resolve, v_val_prev) => {});
  .to((v) => console.log(v));

from realar.

betula avatar betula commented on June 9, 2024

up: replace useMemo by useRef

You may rely on useMemo as a performance optimization, not as a semantic guarantee. In the future, React may choose to β€œforget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without useMemo β€” and then add it to optimize performance.

from realar.

betula avatar betula commented on June 9, 2024

proposal: chain

Think about "chain" abstraction

const a = value(0);
const b = chain(() => a.val);

assert(b.val === undefined);
a(5);
assert(b.val === undefined);

b.input.to(b.output); // "to" better than "watch"
a(6);
assert(b.val === 6);

from realar.

betula avatar betula commented on June 9, 2024

proposal: pool.flat

private finish_purchase = pool(async () => {
    if (this.finish_purchase.count > 1) return; // not count.val here
  });
const a = pool(async () => {
    if (a.count.val > 1) return a.threads[0].promise; // Return promise from first thread
}

assert(a.flat.pending === false);
assert(chan(async () => {}).flat.pending === false);

from realar.

betula avatar betula commented on June 9, 2024

proposal: signal.union

Collect signals from several values and signals.
Worked as last value of set

const a = value(0);
const b = signal(0);

const u = signal.union(a, b);

u.val === 0;
a(5);
u.val === 5;
b(10);
u.val === 10;

from realar.

betula avatar betula commented on June 9, 2024

proposal: chan

Chan - is therm for define async flow.
Previous proposals for async are "flow.async", pipe.

const a = chan(async (p, k, m) => {}, empty_val?);
a(1,2,3);

const b = a.chan(async (a_val, prev_a_val) => {
});

chan(async () => {})
  .flow.filter()
  .flow.filter.untrack(() => this.loaded)
  .watch.once(() => {});

chan.untrack(async () => {})
  .join(b)
  .select(([a,b]) => a + b)
  .flow.untrack(() => {}, empty_val?)
  .watch(() => {})

chan(async () => {}).wrap.filter.not()

// ...

chan.untrack(async () => {}, empty_val)

value.from(() => {})
  .chan(async () => {}, empty_val)
  .flow.untrack(() => {}, empty_val?)
  .flow((a) => a + b.val)
  .watch(() => {});

Chan is not a "pool" because "chan" provides only one value, and flows around that value. Overwise "pool" provides a group of parallel or series async execution processes.

But both these meanings can be used with similar async operators.

const t = value(0)
  .view(() => {})
  .wrap.throttle(300)
  .chan.debounce(300);

// .flow.debounce(300); ??

// const t = pool(async () => {})        // "pool" untracked by default for safety reason
//  .wrap.throttle // hmmm multiples of parameters and throttle can be strange combination.
// Necessary to think about "throttle" and "debounce" for "pool".

Possible typecast syntax

chan(async () => {}).select.untrack(() => {});

signal(0).to.value()     // vs "signal(0).to.value"
value(0).to.signal()
signal(0).to.ready()

signal(0).promise
value(0).promise
value(0).to.ready().promise      // promise recreate on demand     // vs value(0).to.ready.promise

value.flag()
value.flag.not()
value.ready()
signal.flag()            // equivalent to "value.flag"
signal.ready()

// Think about rename "value.ready" to "value.once" or "value.trigger" ...

signal(0).to.trigger()  // The primary candidate for changing to
signal(0).to.once()     // hmm..

from realar.

betula avatar betula commented on June 9, 2024

low: proposal pool single and pool static chaining factory

pool.single(async () => {

})

// or

pool(async () => {

}).single()

// Will be same result
pool.debounce(300).single().flow(async () => {});
// ok

from realar.

betula avatar betula commented on June 9, 2024

low: proposal flow async and error with unhandled flow unsub

const a = value(0);

const b = value(0);
const c = value(0);

// For a first error on next cases
a.flow.async(async (a) => {
  const data = b.flow(() => {}).val; // Error here, necessary for using isolate here
}};


// Flow async proposal

const s = a.flow.async(async (a) => {
  if (!a) return stoppable.stop();

  return await load_subscriptions();
});

s.val // subscriptions or undefined
s.initialized.val
s.error.val
s.pending()

a.flow.async.debounce(300)
  .pipe(
    customDebounce, 
    async (a) => {
      if (!a) return stoppable.stop();
      const m = c.val; // Subscrible to m or not??
      return await load_subscriptions(m);
    }
  ); // readonly async flow

const all_ok = value.combine(a, s.initialized).select(([a, s]) => a && s)  // or value.combine([a, s.initialized])

// Rename pool to asyncs)))

// Constructors

value.async(async (v) => {});
signal.async(async (v) => {});

a.flow.async(async (a) => {});

const m = a.flow.async(async (a) => {}).single();

const h = a.sub.async(reactionable, async (state, val) => {}); // h.pending.val

const h_2 = pool(async (a,b,c,d,e) => {
  stoppable.stop();
});


// Syntax possibilities

a.async
   .debounce(300)
  .pipe(
    customDebounce, 
    async (a) => {
      if (!a) return stoppable.stop();
      const m = c.val; // Subscrible to m or not?? (untrack inside pipe section... hmmmm)
      return await load_subscriptions(m);
    }
  )
  .flow(async (a) => {
    return await load(a, b.val, c.val); // Depend on change any of that values
   })
; // readonly async flow

// Pipe <> Flow same words for not obvious differences... hmm

const s = flow.async(async () => {
  return await load(a.val, b.val, c.val);
});
// Syntax possibilities

const t = a.async
   .debounce(300)
  .flow.untrack(
    customDebounce, 
    async (a) => {
      if (!a) return stoppable.stop();
      const m = c.val;                                       // not subscribe to c
      return await load_subscriptions(m);
    }
  )
  .flow(async (a) => {
    return await load(a, b.val, c.val);              // subscribe to b and c
   })
; // readonly async flow

t.val 
t.ready.val
t.error.val
t.pending.val

// flow factory (only track, untrack unsupported)
const s = flow.async(async () => {
  return await load(a.val, b.val, c.val);
});
const f_sync = flow(() => {
  return sync_load(a.val, b.val, c.val);
});

// And pool

const p = pool(async (a,b,c,d,e) => {
  stoppable.stop();
});

p.pending.val

from realar.

betula avatar betula commented on June 9, 2024

low: proposal pool syntax

const a = pool(async () => {});

a.single()
a.debounce(300)
a.throttle()

// or

a.pipe.single()
a.pipe.debounce(300)

a.pipe( ... ) // what is It?

and for values and signals

const a = value(0);

a.pool.debounce(100) // what is it?

from realar.

betula avatar betula commented on June 9, 2024

low: on((stop) => {}, () => {}) implement

from realar.

betula avatar betula commented on June 9, 2024

low: try deprecate stopppable

selector(init_value?, (stop) => {});
selector((stop?) => {});

cycle((stop) => {});
on((stop) => {}, () => {});




// But I think pool no need to use "(stop) =>" syntax, maybe stoppable() is better for pool?
// pool.stop

pool(async () => {
  const stop = pool.stop;
  pool.stop();
  pool.stop.throw();
});

pool.stoppable((stop) => {
  return async () => {

  }
});

from realar.

betula avatar betula commented on June 9, 2024

low: signal.trigger.from method

Should be added:
signal.trigger.from
signal.trigger.flag.from

from realar.

betula avatar betula commented on June 9, 2024

(Declined) proposal: signal.flag and value.flag

const flag = signal(false).pre((v) => !!v);

from realar.

betula avatar betula commented on June 9, 2024
ver very low: proposal proxy property
const v = value({});
v.proxy.a = 10;
v.update.proxy(p => { // one transaction
  p.b = (p.a += 15);
});

from realar.

betula avatar betula commented on June 9, 2024
proposal: name for production ready version "Universal data-flow"

from realar.

betula avatar betula commented on June 9, 2024
low: think about "in one transaction" feature
const s = signal();
const v = value();

on(s, (s_v) => v.val += s_v);
on(() => [s,v], console.log);


on.transaction(s, (s_v) => v.val += s_v); // used one transaction with changed s

// Think about

from realar.

betula avatar betula commented on June 9, 2024

proposal: queue implementation

const q = queue<Type?>(init?: Type[]);

// q(10); // Think about queue - is a reactive value with set of elements or is the signal for add next one... Hmm.

// q.queue // []

q.front // top
q.back // last element
// q.all // array of elements in queue
q.size
q.clear()

//

q.val
q.first: Value
q.last: Value
q.size: Value
q.active: Value
q.clear()

// Support queue for q.wrap and q.view // think about api
// val: <array_of_elements> readonly
// q(<new_element>)

Or q() - no possible, but 

q.add(value: Type)
q.val: Type
q.first: Value
q.last: Value
q.size: Value
q.active: Value
q.clear()

// How I can make queue with limited size same as in my swipe impl?

q = queue();

q(values: Type[]);
q.set(values: Type[]);
q.update(...);
q.val: Type;

q.add(value: Type);

q.first: Value
q.last: Value
q.size: Value
q.active: Value
q.empty: Value
q.clear()


//

const t = q.first

t.val: Type
t.started: Value
t.start();
t.release(); // remove item from queue (or dequeue)

// or

t.val: Type
t.start: ready(false).to(true)
t.remove(); // remove item from queue // or ready(false).to(true) too

Decorating add signal

const q = queue<Type>([], (queue, value: Type) => {
  const excluded = queue.slice(3);
  // const data = queue..
  // How to convert value to queue element?
});

const q = queue<Type>();
q.before (Signal)

q.before((value) => {
  stoppable.stop();
  transaction
  check q
  remove unnecessary q elems
  add new
  finish transaction
});

from realar.

betula avatar betula commented on June 9, 2024

proposal: interceptor method

const a = value(5);
const b = value(1);

const unsub = a.interceptor((new_value, current_value, stop?) => {
  if (new_value == 1) {
    b.set(10);
    stop();
    return;
  }
  return current_value + new_value;
});
// stoppable supported

a(1); // b.val === 10, a.val === 5
a(2); // a.val === 7

Think about syntax for sub interceptions

const v = value(0);
const s = signal(0);
v.sub.intercept(s, (v_value, new_signal_value, stop ) => {
  ///
});
v.intercept.sub // alias

// or
v.sub.intercept(s, (v_value, new_signal_value, prev_signal_value ) => {
  stoppable.stop();
});
v.intercept.sub // alias

from realar.

betula avatar betula commented on June 9, 2024

proposal: pool async oparators

pool.single(async ({ cancelled }) => {
  const zip = await search();
  if (cancelled()) return;
  return await unpack(zip);
});

// If exists active promise each query return It

// pool.throttle(150, async ({ cancelled, abortController?.., cancel }) => {
pool.throttle(150, async ({ stopped, abortController?.., stop }) => {
  const zip = await search();
  if (zip === 0) stop();
  if (stopped()) return;
  return await unpack(zip);
});

pool.debounce(150, async function * ({ cancel }) {
  const zip = yield search();
  if (zip === 0) cancel();
  return yield unpack(zip);
});

It is offtopic, but I want to think about throttle and debounce for signals:

const start = signal();
const delayedStart = signal.throttle(150, start);

const a = value();
const delayedA = value.throttle(150, a);

const p = pool(async () => await search());
const delayedP = pool.throttle(150, p);

Maybe only one throttle function for all necessaries.

from realar.

betula avatar betula commented on June 9, 2024

low: external package realar-form

from realar.

betula avatar betula commented on June 9, 2024
very low: add jsx method
const a = value(0);

return (
  <p>{a.jsx}</p>
)

return (
  <p>{a.jsx(v => v.map((i, k) => <i key={k}>{i}</i>))}</p>
)

πŸ˜‰

a.jsx
a.jsx.if
a.jsx.else
a.jsx.ifelse
a.jsx.map

// or

jsx(a)
jsx.if(a)
jsx.map(a)
// etc..

For making super performant interfaces πŸ‘

from realar.

betula avatar betula commented on June 9, 2024

very low: state machine impl

This abstraction is necessary for the implementation of serial operations. Reactions on each section of the serial operations.

const m = machine()
  .step(a, () => {})
  .step(b, () => 0)
  .step(machine.oneOf()
    .select(a, () => {})
    .select(b)
    .select(c), () => {})
  .loop();

But I think the yield generator function is an interesting way of decision.

loop(function *() {
  yield a;
  yield b;
  yield loop.oneOf([a, b, c]) // or loop.oneOf().select(a, () => {}).select(b, () => {})... chain function
  yield loop.race([a, b, c])
  yield loop.all([a, b, c])

  // Promise namespace operations for suggest
});

from realar.

betula avatar betula commented on June 9, 2024

low: readonly method

const v = value(0);
const readonly_v = v.readonly();

from realar.

betula avatar betula commented on June 9, 2024

Should research about argument passing to "prop" decorator, for the easy binding reactive container to class property:

class A {
  @prop(this.store) flat_store
}

from realar.

betula avatar betula commented on June 9, 2024

proposal: value.extract

It should be extract object or array of reactive containers to object or array of usual javascript values.

const email = value('a@x');
const values = value.extract({ email });
console.log(values.email) // [email protected]

Possible kinds of name: "values" consistent with useValues

from realar.

betula avatar betula commented on June 9, 2024

proposal: input as exportable api function

input.handler <- (ev) => ev.target.value
// proposal for another names.
// input.delegate
// input.change
// input.event

input.valid
input.valid.pending

input.validator(
  signal<string>().map((state) => /a/.test(state))
)
// input.validator.async() // or

// Interested but no consistency to other code base.
// input.validator((signal) => {
//   return signal.as.chan().map(async () => {})
// });

// Final perfect version
input.validator([
  signal<string>().filter() <-- what will happens if validator will be stopped
  chan<string>().map(async (state) => await fetch_is_valid(state)),
  (state) => /aa/.test(state),
  async (state) => await ext_test(state)
]);

proposal: remove select.multiple

Improve "select" to "select.multiple" signature

const s = select({ a: (state) => state.a });

The argument can be function, reactive container, object map, or array tuple.

proposal: reactive container as argument of "map" (and array of)

const pipe_double = signal<number>().map(state => state * 2);

value(1).map(pipe_double).val // 2
value(1).map([pipe_double, pipe_double]).val // 4

// Use signature as an array or as reactive container, or usual function signature.

from realar.

betula avatar betula commented on June 9, 2024

low: test ts typings

https://github.com/reduxjs/reselect/blob/master/typescript_test/test.ts#L479

 // typings:expect-error     
 const baz2: string = baz;

from realar.

betula avatar betula commented on June 9, 2024

fix: update component warn from modification in the render function

https://codesandbox.io/s/realar-api-unsubscribe-scopes-control-0sziu?file=/src/App.tsx

Warning: Cannot update a component (`fn`) while rendering a different component (`Form`). To locate the bad setState() call inside `Form`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
    at Form (https://0sziu.csb.app/src/App.tsx:30:35)
    at fn (https://0sziu.csb.app/node_modules/realar/build/index.js:697:30)

from realar.

betula avatar betula commented on June 9, 2024

brainstorm: signals two directional synchronization

const a = signal<number>();
const b = signal<number>();

sync(a, b);
sync(b, a);

Signals connection without the infinity loop error

I should realize a way to the bi-directional connection between signals.

const a = signal(0);
const b = signal(0);

sync.bi(a, b);
a.val++
b.val++
assert(a.val === 2)

from realar.

betula avatar betula commented on June 9, 2024

signal.from.select broken ts types with tuples

signal
  .from(() => {
    return [
      buyAnnualLocale.val,
      sharedPurchases().annual_subscription.val
    ]
  })
  .select(([locale, sub]) => { // both variables have one type "string | Subscription | undefined"
    if (!sub) return void 0;
    const localized_price = (sub as any)?.localizedPrice;
    if (!localized_price) return void 0;
    
    return locale.text
  })

from realar.

betula avatar betula commented on June 9, 2024

value(false) broken types for ts <4

const y: Value<boolean> = value(false);
/*
Type 'Value<false, false>' is not assignable to type 'Value<boolean, boolean>'.
  Type 'Value<false, false>' is not assignable to type '{ (value: boolean): void; set(value: boolean): void; }'.
    Types of parameters 'value' and 'value' are incompatible.
      Type 'boolean' is not assignable to type 'false'.ts(2322)
*/

from realar.

betula avatar betula commented on June 9, 2024

proposal: manual rerun cycle outside

const h = cycle(() => {});
h.stop();
h.run();

from realar.

betula avatar betula commented on June 9, 2024

proposal: shortcut not

sharedEye().enabled
    .as.signal()
    .filter()
    .filter(isNext.map(flag => !flag)) // TODO: shortcut not isNext.not()

from realar.

betula avatar betula commented on June 9, 2024

proposal: value with no initial parameter

export const swipeAnimDirection = value<undefined | 'up' | 'down'>();

from realar.

betula avatar betula commented on June 9, 2024

proposal: typings improvement for filter

 value<void | number>()
    .as.signal()
    .filter() // Should remove undefined | null | void from Will signal type
    .to(onlyNumberSignal);

from realar.

betula avatar betula commented on June 9, 2024

proposal: new Scope api

const MyLogic = (initial: string) => {}

const MyScope = scope(MyLogic)

const A = () => {
  const B = useJsx(() => {
    const logic = useScoped(MyLogic)

    /* proposal: use scope logic from local section
    useLocal(() => {
      const logic = scoped(MyLogic)  // Warning scope recreation
      const logic = scoped.current(MuLogic) // Think about
    });
    */
    return
  });
  return <MyScope initial={'hello'}><B>{children}</B></MyScope>
}

from realar.

betula avatar betula commented on June 9, 2024

fix: callback of sync or to methods should be untracked ... hmm.. check it

loader_queue.sync(async queue => {
  // should be untracked here
})

from realar.

betula avatar betula commented on June 9, 2024

fix: typings for select without parameter

  const toggle = value(false).pre((_, state) => !state);
  const enabled = toggle.select(); // Incorrect: ValueReadonly<unknown>

from realar.

betula avatar betula commented on June 9, 2024

proposel: value.will

const t = value.will<number>();
expect(t.val).toBeUndefined();
t.map(n: number => n + 1);

from realar.

betula avatar betula commented on June 9, 2024

proposal

const takeUser = value();
const takeAuth = value();
takeAuth.onChange(takeUser.andUpdate)
takeUser.andSet()
takeUser() - alias for takeUser.andGet

const start = signal();
start.get - doesn't allowed
start.fire(new_value)

takeUser.onChange(start.fire)

start.getValue() - returns value instance

isDirty, isUndefined, isTouched
All methods created only by demand.

start.flow
start.pre

takeUser.compose

from realar.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.