- π₯ harmful -- breaking change
- πΆ maybe harmful -- deprecation, or possible breaking change
- π harmless -- addition, fix, or enhancement
- π add
Content
type, which may be preferable toRenderResult
- π improve
opSignal.load
with deconfliction: now only the latest run will update the signal - π add
OpSignal.load
static helper, to create and start an operation
- πΆ
repeat
function no longer immediately invokes your fn (works more like setTimeout now) - π add export
computed
, alias forsignals.computed
- πΆ fix:
repeat
wasn't supposed to be async
- πΆ deprecated
repeater
in favor of leanerrepeat
implementation- deprecated
Repeater
class is now obsolete - deprecated
repeater.hz
in favor ofrepeat.hz
- deprecated
- π isColorSupported accepts env var
FORCE_COLOR
- πΆ change
Bytename
syllable dictionaries (names will change)
- πΆ change
Bytename
syllable dictionaries (names will change) - π add tools
isNode
isDeno
isColorSupported
- π add tools
templateString
-- template no-op, it's just a stringtemplateParts
-- return the strings and injected valuessvgSlate
-- for ingesting icons in turtlesvgTurtle
-- for ingesting icons in slate, requires manual importimport {svgTurtle} from "@benev/slate/x/tools/svgs/svg-turtle.js"
- π add data tools:
Anka
-- display binary data with random indian charactersBase58
-- standard data encodingBase64
-- standard data encodingBase64url
-- standard data encodingBytename
-- encode arbitrary bytes as human-readable namesBytes
-- helper fns likerandom
to generate random binaryHex
-- encode arbitrary data in hexadecimalText
-- convert between text and bytes
- πΆ rename
generate_id
tohexId
(old name deprecated) - π add tools:
escapeRegex
hash
hat
randomFullName
MemeNames
repeater
- πΆ rename
GoldElement
toShadowElement
- πΆ rename
SilverElement
toLightElement
- πΆ rename
mixin.reactor
tomixin.reactive
- πΆ rename
apply.reactor
toapply.reactive
- πΆ rename
defaultNexus
tonexus
- πΆ rename
apply.context
toapply.setup
- π enhance
use.styles
now accepts any number of stylesheet args// you can now pass multiple stylesheets this way use.styles(cssA, cssB, cssC)
- π enhance
use.css
alias foruse.styles
- π add
mixin.setup
(to matchapply.setup
) - π add new package exports:
lightView
(alias fornexus.lightView
)lightComponent
(alias fornexus.lightComponent
)shadowView
(alias fornexus.shadowView
)shadowComponent
(alias fornexus.shadowComponent
)shadowComponentify
(alias fornexus.shadowComponentify
)component
(alias fornexus.component
)components
(alias fornexus.components
)
- πΆ tweak generic type signature on
Pool
- πΆ deprecated
explode_promise
(preferdeferPromise
) - π add: tool
concurrent
- π add: tool
deferPromise
- π add: tool
deadline
- π enhance:
pubsub
- added new
once
method - now you can subscribe async functions
- publish now returns a promise, to wait for all subscribers to finish working
- added new
- πΆ ts target
es2023
, seems all evergreen browsers support it - πΆ deprecated
maptool
in favor ofMap2
- π add: tool
requestAnimationFrameLoop
- π add: tool
Map2
facility will replace maptool
- π add
use.deferOnce
- πΆ deprecated
is.void(x)
, renamed tois.unavailable(x)
- πΆ deprecated
is.defined(x)
, renamed tois.available(x)
- π₯ camel case!
light_view
is nowlightView
light_component
is nowlightComponent
shadow_view
is nowshadowView
shadow_component
is nowshadowComponent
- π₯
use.defer
- now returns a
Signal
- it used to directly return a value
- the reason for this change, was that the old way created a footgun where it's very easy to accidentally hold an old reference to the deferred value that you wanted. so, now using a signal, your access to the signal's value is more likely to be an up-to-date reference
- now returns a
- op loading effects
- π₯
prep_op_effect
replaced bymakeLoadingEffect
ormakeAnimatedLoadingEffect
- π added
loading
effects likeloading.binary(op, onReady)
andloading.braille(op, onReady)
- π₯
- π₯ eliminated
@benev/slate/x/pure.js
- beware if you are using slate in a node.js environment
pure.js
was an alternative entrypoint for node to import the parts of slate that didn't touch any DOM apis- instead, now, if you are importing slate into node, you should do this first:
import "@benev/slate/x/node.js"
- all this does is assign
global.HTMLElement = class {}
because extending HTMLElement is the only contact that slate has with the dom at import time - thus, the new
node.js
is a little shim that lets you import all of slate in node (maybe for unit testing or to use some tools)
- π₯
interval
tool: changed arguments- now it accepts plain milliseconds
- whereas the new
interval.hz
accepts hertz, replacing what used to be calledinterval
- thus, to upgrade, replace
interval(1, fn)
withinterval.hz(1, fn)
- πΆ deprecate
signal.subscribe
in favor ofsignal.on
- πΆ deprecate tools:
Trashcan
(in favor ofTrashbin
)pub
(in favor ofpubsub
)
- π added
use.load
helper for creating an op and immediately initiating a load operation - π added tools:
wherefor
ref
andRef
- πΆ added
watch.wait
promise, because watch tower dispatches are now debounced
- πΆ rename
FancyEventListener
toLitListener
- π add: tools
ev
,Trashcan
,litListener
, andpubsub
- π views now expect a relaxed template type,
RenderResult
, which means views can return other views and strings etc
nexus rewrite
- π₯
Slate
renamed toNexus
- π₯ silly names have been purged
- renamed
ObsidianRenderer
toShadowViewRenderer
- renamed
CarbonRenderer
toShadowComponentRenderer
- renamed
QuartzRenderer
toLightViewRenderer
- renamed
OxygenRenderer
toLightComponentRenderer
- tons of renames following the same pattern have occurred
- renamed
shadow views and components
- π₯ simpler syntax: remove settings array, in favor of new hooks
- old way
slate.shadow_view({name: "coolview", styles}, use => () => { return html`hi` })
- new way
slate.shadow_view(use => () => { use.name("coolview") use.styles(styles) return html`hi` })
- old way
use
- π₯
use.setup
renamed touse.mount
- π₯
use.prepare
renamed touse.once
- π₯ renamed various types and helpers
- types
SetupFn
toMount
Setdown
toUnmount
InitFn
toInit
- helpers
setupFn
tomountFn
- types
- π add hook
use.effect(fn, dependencies)
(all views and components) - π add hook
use.defer(fn)
(all views and components) - π add hook
use.name(name)
(all views) - π add hook
use.styles(styles)
(shadow_view and shadow_component)
views
- π₯
<obsidian-view>
renamed to<slate-view>
- π₯ light_view (quartz) contents are now wrapped in
<slate-view>
- this is to provide an anchor point from which the view can query its own contents
- this also helps light_view behavior match shadow_view
ops (and OpSignal)
- π₯ rename
Op.run
toOp.load
- also rename
OpSignal->run
toOpSignal->load
- also rename
- π₯
Op.load
andOpSignal->load
now throws errors- it still sets the op to an error state
- but now it also throws an error, so you can catch it directly
- π₯ rename op 'mode' to 'status'
- change
Op.Mode
toOp.Status
- change
op.mode
toop.status
on your op objects
- change
- π₯ rework OpSignal checkers, from getters to functions
- change
op.loading
toop.isLoading()
- change
op.error
toop.isError()
- change
op.ready
toop.isReady()
- this was necessary for the new form to be proper ts type guards
- change
- π fix checkers like
Op.is.loading
to have proper ts type guards - π fix signals.op return type to be OpSignal
tools
- π₯ rename
MapSubset
type toMapBase
- π₯ rename
maptool(map).grab(..)
tomaptool(map).guarantee(..)
- π export
mapGuarantee(map, k, v)
function, technically more efficient thanmaptool(map).guarantee(k, v)
- π₯ rework
ob
tool syntaxob.map(object, transform)
becomesob(object).map(transform)
ob.filter(object, predicate)
becomesob(object).filter(predicate)
- π₯ recapitulated
deepEqual
anddeepFreeze
into newdeep
tooldeepEqual
becomesdeep.equal
deepFreeze
becomesdeep.freeze
- both functions have been reworked to handle maps and sets
- π add
is
tool- proper typescript type guard support
is.object(x)
is.array(x)
is.defined(x)
watch
- π₯
watch.track
now returns an unsubscribe function, instead of the collector's data- if you need the data from your collector, just run the collector yourself
- π add
Historian
andAppCore
for creating apps with undo/redo capabilities
in this recent work, the flat
and signals
state management apis are converging.
- π₯ removed synonyms
slate.carbon
,slate.oxygen
,slate.obsidian
,slate.quartz
- now you should use
slate.shadow_component
,slate.light_component
,slate.shadow_view
,slate.shadow_component
respectively
- now you should use
- π₯
flat
breaking changes- removed
.manual
,.auto
,.deepReaction
- flat now implements
ReactorCore
.reaction
always has debouncing and discovery enabled.wait
to wait for the debouncer to fire responders.lean
for advanced integrations
- removed
- π₯
signals
breaking changes- removed
.track
(now you should use.reaction
instead) - signals now implements
ReactorCore
.reaction
always has debouncing and discovery enabled.wait
to wait for the debouncer to fire responders.lean
for advanced integrations
- removed
- πΆ the way reactivity works has been rewritten, so be wary of new bugs
- the flatstate and signals mixins have been rewritten using the new
.lean
methods - the internal
setup_reactivity
for slate components and views has been rewritten using the reactor's.lean
- the flatstate and signals mixins have been rewritten using the new
- π added new state management system called
reactor
- implements
ReactorCore
(has.reaction
,.wait
, and.lean
) - reactor combines both flatstate and signals reactivity
- so you can make reactions that listen to both flatstates and signals
- see usage examples in the readme
- implements
- π added new
mixin.reactor
andapply.reactor
- this is how you can mixin
reactor
support for your own elements, thus adding reactivity for both flatstate and signals at once
- this is how you can mixin
- note, there are no changes to
watch
watch
is fundamentally different than flatstate and signals, and is not suitable to become a ReactorCore- watch does not have any "automated" reactivity, it's always explicit, so it has
.track
instead of.reaction
- π₯ change Initiator signature, added
.cleanup
helpers
- π₯ replace WatchBox with Signal
- π₯ WatchTower now requires SignalTower as a param
- π add exports 'flatstate' and 'signal'
- π add ZipAction.prep, ZipAction.prepAction, ZipAction.prepBlueprint
- π₯
flat
,signals
, andwatch
removed fromContext
// now we do this import {flat, signals, watch} from "@benev/slate"
- π₯
setup
replaced withSlate
class// old const slate = setup(context) // new const slate = new Slate(context)
- slate.shell has been
deleted
-- now Slate extends Shell (slate is a shell now)
- slate.shell has been
- π₯ renamed
prepare_frontend
tosetup
- π added synonyms
carbon
=>shadow_component
oxygen
=>light_component
obsidian
=>shadow_view
quartz
=>light_view
- π₯ significant rework
- introduce experimental new
context.watch
WatchTower and StateTree systems - rename
context.tower
tocontext.signals
prepare_frontend
usage changes- new pattern returns the "slate" object
- "slate.carbon", "slate.obsidian", etc
- now setting of context can be deferred to runtime
slate.context = new Context()
- this made
deferred_frontend
obsolete, so we deleted it
- prepare_frontend's component helper has changed
- plain components, like gold and silver, no longer need any helper
- now you must use the new
slate.components
helper to apply the current context to a group of plain components, at runtime, prior to registration (if you want the components to be reactive and use the css theme)
- change
Attributes.base
toattributes
- introduce experimental new
- π₯ massive rework
- deleted shale and clay views
- added obsidian/quartz views
- added carbon/oxygen elements
- rework prepare_frontend system entirely
- rework context
- add signals