Npm

Constants

As the name suggests, constants are values passed down in your context that cannot be changed. Constants are useful for providing things like configuration and styles to your subscribed components.

Constants are defined in an object, and are added to your CF instance via the method.

Note that you can also include functions in your constants definition. However, Unlike and , any function defined in your constants will not be bound to your provider component, and will therefore not have a keyword associated with the provider/context. This is fine for utility functions which do not require knowledge of state or setters.

Setters

Dynamic Setters

Dynamic setters are automatically generated functions that can perform state updates on single properties in your state. They are generated based on your your default state. For example, if you have a state property called , a dynamic setter would be created called , and any argument passed to would set in state to that argument value

Dynamic setters are turned on by default, and can be turned off by passing to your CF initialization.

With that initialization, your object now has a method, and you can do something like the following.

In the event that you wish to use a dynamic setter to set the value based on the previous state, you have two options.

Option 1: Use async/await

By the end of this state transaction, myValue will be increased by 3. This is very clean and concise, but requires the setter call to be wrapped in an async function. Additionally, because the keyword will block execution, excessive use of this pattern can cause a minor performance hit.

Option 2: Pass a function as the argument

This will also result in being increased by 3. This is slightly more verbose, but does not require that the setter call be wrapped in an async function.

Nested Setters

If you initialize you CF instance with the option, you will get dynamic setters for any nested properties in your state.

Now, if you check what setters are available in your setters object, you’ll find one named . Nested setters work the same as any other dynamic setter. Note that the path to the nested property is delimited by an underscore. This is the naming convention for nested setters.

Custom Setters

Dynamic setters only allow you to set a single state property at a time, and to the single value that is passed as an argument to the setter. If you desire lower level control over the state change for a specific property, or you want to update multiple state properties with one method, you can add custom setters to achieve these goals.

Custom setters are just methods that get bound to the provider component, and typically internally call . Nothing enforces that custom setters must call , but it is recommended that you maintain this pattern for predictable functionality.

Custom setters are added via the method available on the CF instance.

In the above example, we have a state with a and . When a user logs out, we probably want to clear all user related fields. With the dynamic setters of CF, we could accomplish this in two calls: , and . Since the logout behavior will always change both, it makes more sense to bundle these state operations together. Our custom setter above does just that, so we now have a convenient, and syntactically correct setter to call to logout a user.

Custom setters are accessed in the same way as dynamic setters.

A note on

Custom setters internally call . Inline with the focus on familiarity, works as you would expect from vanilla React. However, Cantus Firmus allows for the extended ability to use the async/await syntax with .

If you are performing a state change that requires information from the previous state, the vanilla React pattern is to pass a function with the previous state as the first argument. This is because React batches state changes, and you cannot be sure that the current value in state will be the same when you execute your setter function. This will still work in CF, but you may also use setState with async/await.

The following two examples accomplish the same thing. They both increase some value in state by 1 while referencing the current value in state.

Also of note, returns a promise in CF. One completed, the promise resolves to the newly updated state.

Persisting State with Local Storage

Persisting state over page reloads is very easy with CF. If you set to true, your main/provider window will load default state values from those specified in the local storage. If this is the desired functionality, make sure to also set to false, so the local storage persists in that domain even if the user leaves the page.

If there are some state values that you wish not to initialize from local storage, you can set them in the parameter. Any value indicated in this parameter will not ever be saved to local storage. If you are initializing from a persisted local storage, and have private state values specified, those values will initialize to whatever you have set in your default state object.

Reducers

For those how prefer the reducer/dispatch format for setting state, you can add custom reducers to your CF instance with the method. Reducers are just functions that return the updated (not directly mutated) state.

We can define multiple reducer functions to separate the logic of our state changes. In the above example, we have one reducer that handles updates to the properties, and one that updates the properties.

Internally, a dispatch function is generated for each reducer. When you access reducers in a child component, you aren’t actually accessing the reducer that you made, but an object containing these auto generated dispatch functions namespaced to the reducer name you specified. When we want to execute a specific action, we do the following:

Like the modified , the generated dispatch function is asynchronous. It returns a promise that resolves to the updated state. So something like the following will work (though it’s not necessarily recommended):

History

The earliest polyphonic compositions almost always involved a cantus firmus, typically a Gregorian chant, although the term itself was not used until the fourteenth century. The earliest surviving polyphonic compositions, in the Musica enchiriadis (around 900 C.E.), contain the chant in the top voice, and the newly-composed part underneath; however this usage changed around 1100, after which the cantus firmus typically appeared in the lowest-sounding voice. Later, the cantus firmus appeared in the tenor voice (from the Latin verb ‘tenere’, to hold), singing notes of longer duration, around which more florid lines, instrumental and/or vocal, were composed.

Thirteenth Century

Compositions using a cantus firmus continued to be the norm through the thirteenth century. Almost all of the music of the St. Martial and Notre Dame schools uses a cantus firmus, as well as most thirteenth century motets. Many of these motets were written in several languages, with the cantus firmus in the lowest voice; the lyrics of love poems might be sung in the vernacular above sacred Latin texts in the form of a trope, or the sacred text might be sung to a familiar secular melody.

Fourteenth Century

In the fourteenth century, the technique continued to be widely used for most sacred vocal music, although considerable elaboration began to appear—while most continental composers used isorhythmic methods, in England other composers experimented with a «migrant» cantus firmus, in which the tune moved from voice to voice, however without itself being elaborated significantly. Elaborations came later, in what was to be known as the paraphrase technique; this compositional method became important in composition of masses by the late fifteenth century. (See paraphrase mass.)

Sacred Cantus Firmus


First bars of Missa L’Homme armeé by Johannes Ockaghem. L’Homme armeé–cantus firmus shown in red.

The cyclic mass, which became the standard type of mass composition around the middle of the fifteenth century, used cantus firmus technique as its commonest organising principle. At first the cantus firmus was almost always drawn from plainchant, but the range of sources gradually widened to include other sacred sources, and even popular songs. Also the cantus firmus was at first restricted to the tenor, but by the end of the century many composers experimented with other ways of using it, such as introducing it into each voice as a contrapuntal subject, or using it with a variety of rhythms. During the sixteenth century the cantus firmus technique began to be abandoned, replaced with the parody (or imitation) technique, in which multiple voices of a pre-existing source were incorporated into a sacred composition such as a mass. Yet while composers in Italy, France, and the Low Countries used the parody and paraphrase techniques, composers in Spain, Portugal, and Germany continued to use the cantus firmus method in nationally idiosyncratic ways.

German composers in the Baroque period in Germany, notably Bach, used chorale melodies as cantus firmi. In the opening movement of Bach’s St. Matthew Passion, the chorale «O Lamm Gottes, unschuldig» appears in long notes, sung by a separate choir of boys «in ripieno.» Many of his chorale preludes include a chorale tune in the pedal part.

Secular Cantus Firmus

Probably the most widely set of the secular cantus firmus melodies was L’homme armé. Over 40 settings are known, including two by Josquin Desprez, and six by an anonymous composer or composers in Naples, which were intended as a cycle. Many composers of the middle and late Renaissance wrote at least one mass based on this melody, and the practice lasted into the seventeenth century, with a late setting by Carissimi. There are several theories regarding the meaning of the name: one suggests that the «armed man» represents St Michael the Archangel, while another suggests that it refers to the name of a popular tavern (Maison L’Homme Armé) near Dufay’s rooms in Cambrai. Being that this music arose shortly after the Fall of Constantinople in 1453, it is possible that the text «the armed man should be feared» arose from the fear of the Ottoman Turks, who were expanding militarily towards central Europe. There are numerous other examples of secular cantus firmi used for composition of masses; some of the most famous include ‘Fortuna Desperata’ (attributed to Antoine Busnois), ‘Fors seulement’ (Johannes Ockeghem), ‘Mille regretz’ (Josquin), and ‘The western wynde’ (anonymous).

Namespaced Methods

Namespaced methods allow you to segment your methods based on function by giving them unique names. The resulting method groups in your context value will be identical to the value described above in that they are simply functions that will have access to the keyword.

For example, if you had a set of methods that accessed some REST API, and another set of methods that derived values from multiple parts of you state, you may want to segment the logic of those two groups so that you are not accessing the value from your context for both. The instance method allows you to do this very easily.

Now, in your context value, you will have access to and as separate method groups.

Defining Custom Setters & Methods

You define your custom setters and methods as functions in a standard JS object. When you add them to your CF Instance, they get bound to the provider component so that you have access to the keyword. Since custom setters and methods will require a keyword, you cannot use arrow functions when you define them.

Setters Vs Methods

Setters and methods may seem rather similar as they are just collections of functions bound to a provider component. While you can substitute one for the other in any situation, they have been provided as separate utilities so that their function and purpose do not conflict.

Setters are intended to house the logic that changes state. Each setter should call . Methods are a level of abstraction higher. They should not concern themselves with directly setting state or any of the logic that is required in that action. Rather, they allow for simple access to state and setters, and house any logic that later calls on these items.

CLI Flags & Options

If you run the cli without any options or flags set, you will be taken to a setup wizard which will walk you through setting up your CF instance. Simply follow the instructions printed to your terminal.

Specifying a Name

The first parameter you might set is the name of your state manager.

The above with create a directory called inside your state management directory. With this command, you will still be walked through the setup wizard to select your desired support files.

Support File Flags

If you indicate any of the flags below, a support file for that item will be created, and it will automatically be added to your CF instance.

Flag Support File Description
-s state.js Default state
-c setters.js Custom setters
-m methods.js Custom methods
-r reducers.js Custom Reducers
-k constants.js Constants

Example:

In the example below, a file called will be created for you housing the CF instance configuration, as well as three support files, , , and . These will all be saved into a directory called .

Changing Default Names

If you want to change the name of a support file to be more syntactically correct based on your usage, you can do that by specifying . If you specify a support file in this way, you do not need to include its flag also.

Possible support file names are , , , , and,

Example:

Now, rather than a file named , you will have a file called . Note that this only changes the file name, and not the name within your CF instance. If you want the value in your context to also be named , make sure to use the CF instance’s method to do so.

As the example above shows, you can combine flags and rename files in the same command. The above will create the following state management resource for you:

История

Термин впервые появляется в теоретической сочинения начала 13 века (например, Boncampagno da Signa, Rhetorica novissima, 1235). Самые ранние полифонические композиции почти всегда включали cantus firmus, обычно григорианское пение, хотя по соглашению этот термин не применяется к музыке, написанной до 14 века. Самые ранние сохранившиеся полифонические композиции в Musica enchiriadis (около 900 г. н.э.) содержат пение в верхнем голосе и недавно составленную часть внизу; однако это использование изменилось около 1100 г., после чего cantus firmus обычно появлялся самым тихим голосом. Позже в голосе тенора (от латинского глагола tenere, удерживать) появилась cantus firmus, поющая ноты большей продолжительности, вокруг которых были сочинены или импровизированы более витиеватые строки, инструментальные и / или вокальные.

Композиция с использованием cantus firmus продолжала оставаться нормой на протяжении 13 века: почти вся музыка St. В школах боевых искусств и Нотр-Дам используется cantus firmus, как и в большинстве мотетов 13 века. Многие из этих мотетов были написаны на нескольких языках, при этом cantus firmus звучал самым низким голосом; стихи любовных стихов могут петься на народном языке над священными латинскими текстами в форме , или священный текст может быть спет на знакомую светскую мелодию.

В XIV веке эта техника продолжала широко использоваться в большинстве духовных вокальных произведений, хотя начали появляться значительные разработки: в то время как большинство континентальных композиторов использовали изоритмические методы, в Англии другие композиторы экспериментировали. с «мигрирующим» cantus firmus, в котором мелодия переходила от голоса к голосу, но сама не претерпевала значительных изменений. Позже появились разработки, которые впоследствии стали известны как метод перефразирования ; к концу 15 века этот композиционный прием стал важным в композиции масс. (См. перефразировать массу.)

Циклическая масса, которая стала стандартным типом композиции масс примерно в середине 15 века, использовала технику cantus firmus в качестве своей самый общий организационный принцип. Сначала cantus firmus почти всегда брали из plainchant, но постепенно круг источников расширился, включив в него другие священные источники и даже иногда популярные песни. Поначалу кантус твердый был ограничен тенором, но к концу века многие композиторы экспериментировали с другими способами его использования, такими как введение его в каждый голос в качестве контрапункта или использование его с различными ритмами. В течение 16 века от техники cantus firmus начали отказываться, заменив ее техникой пародии (или имитации), в которой несколько голосов ранее существовавшего источника были включены в священную композицию, такую ​​как месса. Тем не менее, в то время как композиторы в Италии, Франции и Нидерландах использовали техники пародии и перефразирования, композиторы в Испании, Португалии и Германии продолжали использовать метод cantus firmus национально идиосинкразическими способами.

Вероятно, наиболее широко распространенный. из светских мелодий cantus firmus была «L’homme armé «. Известно более 40 настроек, в том числе два от Жоскена де Пре и шесть от анонимного композитора или композиторов из Неаполя, которые задумывались как цикл. Многие композиторы среднего и позднего Возрождения написали по крайней мере одну мессу на основе этой мелодии, и эта практика продолжалась до семнадцатого века с поздней постановкой Кариссими. Существует несколько теорий относительно значения этого имени: одна предполагает, что «вооруженный человек» представляет святого Михаила Архангела, а другая предполагает, что это относится к названию популярной таверны (Maison L’Homme Armé) около Дюфе. в Камбре. Поскольку эта музыка возникла вскоре после падения Константинополя в 1453 году, вполне возможно, что текст «следует опасаться вооруженного человека» возник из-за страха перед турками-османами, которые расширялись в военном отношении в сторону Центральной Европы. Есть множество других примеров светских cantus firmi, используемых для композиции масс; некоторые из самых известных включают: «Se la face ay pale» (Дюфай), «Fortuna desperata » (приписывается Антуану Буснуа ), «Fors seulement «(Йоханнес Оккегхем ),« Милле Регрец »и« Вестрон Винд »(анонимно).

Немецкие композиторы периода барокко в Германии, особенно Бах, использовали хоральные мелодии как cantus firmi. Во вступительной части баха Страсти по Матфею хорал «O Lamm Gottes, unschuldig » появляется в длинных нотах, спетых отдельным хором мальчиков »в ripieno ».

Initialization Options

Option Type Default Description
dynamicSetters Boolean true specifies if setters should be dynamically generated based on the provided state object.
dynamicGetters Boolean true specifies if getters should be dynamically generated based on the provided state object.
nestedSetters Boolean false Specifies if setters should be dynamically created for nested state values.
nestedGetters Boolean true Specifies if getters should be dynamically created for nested state values.
allowSetterOverwrite Boolean true If true, allows a custom defined setter to overwrite the functionality of a dynamic setter of the same name.
developmentWarnings Boolean true if is false, developmentWarnings will warn the developer if they try to overwrite a dynamic setter with custom logic.
overwriteProtectionLevel Number (0, 1, >= 2) 1 if is false, sets the warning type that a developer will get when overwriting a dynamic setter. will silence warnings, print a console.warn message, and 2 or greater will throw an error and halt execution.

Methods

It may be the case that you have some helper function that requires access to state and/or state setters. In vanilla React, you would have to pass your state and setters as arguments to the helper function and then reference/execute them within the scope of that helper function. Cantus Firmus provides a much simpler way of accomplishing this via .

In CF, you can add custom methods to your CF instance that, like custom setters, get bound to the provider component and get access to the keyword. These methods can then access and internally, without you having to pass them in as arguments. This can greatly simplify your code.

Methods are added to your CF instance via the method.

A common use for methods might be to send API calls and then set state based on the response.

In the above example, we access both and . Now, we can simply call without having to pass in state or setters and it will automatically call and set our state for us.

Getters

In most cases, the easiest way to access your CF instance state is by the standard dot notation.

However, there are situations, such as closures, where this way of accessing state may become problematic.

In the above example, inside the callback, we have defined an interval that performs some action every second so long as in the state is truthy. Presumably, we would want to be able to change the value of to something falsy in some other component, and to have that cancel the interval. Due to the closure, this will not work as will be set inside the interval callback to whatever its initial value was, and no updates will be read.

For situations such as these, all CF contexts are initialized with dynamic getter methods by default. As the name implies, these getters serve as wrappers by which to access your state. Just as we get a object in our context, we also get a object that is auto populated with getter functions. The syntax is also similar to our setters: if you have a value, , you will then have a getter called . If you require nested getters, you can set to in your CF initialization. Nested getters would then look something like

We can very easily change the code above to work with one of these dynamic getters.

Now, each time the interval is run, it accesses the property in our state via the getter, , and so updates to the property are observed.

In short, getters are an excellent option for any situation where closures prevent state updates from being observed.

Inter-Window Communication through Local Storage

Local storage is synced between all windows on the same domain. In saving our state to local storage, it becomes available to all other open windows on that domain. Even though this is the default behavior of your browser, there is still typically substantial work that goes into managing state across windows. Cantus Firmus handles many common scenarios in the background, such as listening for local storage updates and then updating the window’s state. It also provides a custom method for spawning new windows and keeping track of those spawned windows.

Just like the provider/subscriber pattern in React context, windows are organized into provider and subscriber roles. The original window becomes the provider, and all children spawned from it with the windowManager become subscribers. Provider windows will have access to the whole state object. Subscribers only have access to those state parameters not set in .

WindowManager

Each CF instance connected to local storage gets a windows manager. The window manager has three methods:

Name Arguments Description
open url: string, name: string, params: object Opens a new window and keeps reference to that window locally so it can later close it. The url and name arguments are both required. The params object is options and allows you to set query params on the new window
close name: string Closes the target window with the given name. Note that it is best to close a window through this method as it will also remove the local reference to that window. If you close a window without this method, the reference will still exist in the provider window.
getChildren none Returns an object with references to all spawned windows.

A CLI is included with the Cantus Firmus install, and it allows you to quickly create a CF state manager and associated support files (setters, methods, etc.).

ConnectToLocalStorage

Cantus Firmus makes two typically challenging scenarios quite simple to achieve: state persistance, and sharing state between windows under the same domain. Both are accomplished by saving and updating state in the browser’s local storage.

Connecting a CF instance’s state to local storage is done through the method. There are several options that can be defined when establishing this connection.

ConnectToLocalStorage Options:

Option Type Default Description
name String (required) null A string that is unique from any other key name (including any other names set in other CF instances). This will become the key name under which the instances state is stored in .
initializeFromLocalStorage Boolean false Specifies if the state should be loaded from the rather than with the default initialization values. Note that if the does not contain a reference to the state, default values will be loaded. Regardless of what value is set in this field, windows with names provided in the parameter will initialize from localStorage.
providerWindow String null Specifies the property of the parent window. If no value is given, it will default to the same string specified in the option.
subscriberWindows Empty Array An array of strings that has a comprehensive list of the names of the windows that may subscribe to the shared state through . These windows will automatically initialize from localStorage regardless of the value set in
removeChildrenOnUnload Boolean true If true, will close all children windows spawned from the method. Note that if a child window spawns another window (grandchild), that window will also be closed if this parameter is set to true.
clearStorageOnUnload Boolean true If true, when the is closed, all associated state stored in will be removed.
privateStatePaths ] Empty Array Specifies state parameters of the provider window that will not be saved to local storage. Elements in the array may be strings or arrays of strings. The latter options allows for you to specify a nested parameter as private while still passing parameters higher in the state structure. This feature is useful if you do not wish to share parts of your state with child/grandchild windows, or if you have marginally sensitive data in your state and do not wish to expose it to local storage.

Instance Methods

Name Arguments Description
addCustomSetters Setters Object The setters object contains custom setter methods that internally call . See for more detail.
addMethods Methods Object The methods object contains custom methods that internally have access to the keyword, and can therefore access the instance state and setters. See for more detail.
addNamespacedMethods (v0.1.4+) Namespaced Methods Object Like , allows you to create custom functions that have internal access to the keyword. Rather than providing a single methods object, you provide an object with keys pointing to multiple method objects. See for more detail.
addReducers Reducers Object The reducers object contains custom reducer methods. See for more detail.
addConstants Constants Object The constants object is a standard JS object with properties and methods. As the name indicates, these values are not configurable after initialization. Useful for passing down configuration, styles, or helpers methods in your context. Note that any methods added here will not be bound to the provider component, and therefore will not have access to the keyword to reference state, setters, etc.
ignoreSetters ] The method is used in conjunction with dynamically generated setters. You may pass in the name of any state property as a string (top level or nested), and no setter for the property will be created. Note that you may still add a custom setter of the same name and this will be included. If your array contains an array of strings, this will be considered the path to a nested value.
ignoreGetters ] The method is used in conjunction with dynamically generated getters. You may pass in the name of any state property as a string (top level or nested), and no getter method for the property will be created. Note that you may still add a custom getter of the same name and this will be included. If your array contains an array of strings, this will be considered the path to a nested value.
rename Name Map Object The method allows you to rename any property passed in the instance context. This is typically done for symantec reasons. For example, if you passed in {methods: «API»}, you can now destructure from your context value to reference all your methods. This also adds an internal reference, so you could also access from your custom setters, for example.
connectToLocalStorage Options Obeject Duplicates local state to the browser’s local storage for persistence or for sharing between multiple windows under the same domain. See for more detail.

Efficient Updating

Subscriber

CF is built on the React context API. While it inherits the ease of use from React Context, it also inherits some efficiency pitfalls regarding subscriber component updates and re-renders. CF comes with a custom wrapper that uses React’s memoization to mitigate these issues and prevent unnecessary re-renders. It is very easy to refactor a component to use the HOC.

Rather than subscribing to a context via traditional means like , or the hook, we use the included wrapper. It is even possible to subscribe to multiple contexts this way.

Components that subscribe to contexts in this way receive those contexts via their props. The function takes in two arguments: your component, and an array of context definitions and relevant dependencies.

Context definitions are just objects with the following properties:

Name Type Required Description
context React Context true A reference to a context
key String false Defines how the context will be named when it is passed down in props. If omitted, it will default to the following naming convention: if only one context is passed, it will be called «context». If multiple contexts are passed and keys are omitted for all of them, the first context will be named «context1», the second, «context2» and so on.
dependencies ] true An array of strings listing the context properties that should trigger a re-render if changed. Nested properties can be indicated by passing an array of strings into the dependency array.

Credits

New World Encyclopedia writers and editors rewrote and completed the Wikipedia article
in accordance with New World Encyclopedia standards. This article abides by terms of the Creative Commons CC-by-sa 3.0 License (CC-by-sa), which may be used and disseminated with proper attribution. Credit is due under the terms of this license that can reference both the New World Encyclopedia contributors and the selfless volunteer contributors of the Wikimedia Foundation. To cite this article click here for a list of acceptable citing formats.The history of earlier contributions by wikipedians is accessible to researchers here:

Cantus firmus  history

The history of this article since it was imported to New World Encyclopedia:

History of «Cantus firmus»

Note: Some restrictions may apply to use of individual images which are separately licensed.

Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Музыкальная гитара
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: