Proposal: The internal modifier for classes

The internal modifier
Often there is a need to share information on types within a program or package that should not be
accessed from outside of the program or package. While the public accessibility modifier allows
types to share information, is insufficient for this case as consumers of the package have access
to the information. While the private accessibility modifier prevents consumers of the package
from accessing information from the type, it is insufficient for this case as types within the
package also cannot access the information. To satisfy this case, we propose the addition of the
internal modifier to class members.
Goals
This proposal aims to describe the static semantics of the internal modifier as it applies to members of a class (methods, accessors, and properties).
Non-goals
This proposal does not cover any other use of the internal modifier on other declarations.
Static Semantics
Visibility
Within a non-declaration file, a class member marked internal is treated as if it had public
visibility for any property access:
source.ts:
class C {
    internal x: number;
}

let c = new C();
c.x = 1; // ok

When consuming a class from a declaration file, a class member marked internal is treated as
if it had private visibility for any property access:
declaration.d.ts
class C {
    internal x: number;
}

source.ts
/// <reference path="declaration.d.ts" />
let c = new C();
c.x = 1; // error

Assignability
When checking assignability of types within a non-declaration file, a class member marked
internal is treated as if it had public visibility:
source.ts:
class C {
    internal x: number;
}

interface X {
    x: number;
}

let x: X = new C(); // ok

If one of the types is imported or referenced from a declaration file, but the other is defined
inside of a non-declaration file, a class member marked internal is treated as if it had
private visibility:
declaration.d.ts
class C {
    internal x: number;
}

source.ts
/// <reference path="declaration.d.ts" />
interface X {
}

let x: X = new C(); // error

It is important to allow assignability between super- and subclasses from a declaration file
with overridden members marked internal. When both types are imported or referenced from a
declaration file, a class member marked internal is treated as if it had protected visibility:
declaration.d.ts
class C {
    internal x(): void;
}

class D extends C {
    internal x(): void;
}

source.ts
/// <reference path="declaration.d.ts" />
let c: C = new D(); // ok

However, this does not carry over to subclasses that are defined in a non-declaration file:
declaration.d.ts
class C {
    internal x(): void;
}

source.ts
/// <reference path="declaration.d.ts" />
class D extends C {
    internal x(): void; // error
}

Would the following also error:
declaration.d.ts
class C {
    internal x(): void {};
}

source.ts
/// <reference path="declaration.d.ts" />
class D extends C {
    x(): void {}; // error?
}

How does this differ from the more common language semantic protected?
The non-goal is not to address this in other declarations, but couldn't this start to becoming confusing for someone trying to utilise a package or library?  For example, I would assume the following you would want to work this way:
declaration.d.ts
interface InterfaceC {
}

class C implements InterfaceC {
    internal x(): void {};
}

source.ts
/// <reference path="declaration.d.ts" />
class D implements InterfaceC {
}

const c: C = new D(); // error, but why? I implemented the interface properly.

When targeting ES6, do you see any changes, considerations in the emit?
Do you have a more practical use case of where this pattern would resolve significant problems?  I can understand how for a consumer it could clean up an API, but at the same time, it could be really confusing where you are "hiding" things that will always exist at runtime from compile time.  It almost seems like a six of one, half a dozen of another.

An alternative to modifiers is:
package.d.ts
/// <reference path="declaration.d.ts" />
internal {
   C.x;
}

An internal {} block marks which parts of the public api are hidden.

+1 to something like this

+1 for this.

Internal modifier for classes and their properties/methods within a component/program would allow greater scope for Typescript identifier shortening.
+1 for this proposal.

I think I'd want to extend internal to also work on classes.
It would work pretty much like the --stripInternal compiler flag works now, except without the need to add JSDoc to the class.
Additionally, though this may need some exploring, it could be used to keep classes within a module. So for example:
//file1.ts
module A.B
{
    internal class C { }

    var c: C = new C(); //Works
}

//file2.ts
module A
{
     var d: A.B.C = new A.B.C(); //Error because C is only available inside A.B module scope.
}

//file3.ts
module A.B
{
    var e: A.B.C = new A.B.C(); //Works, back in scope
}

I'm polishing classes' members' openness of RxJS like https://github.com/ReactiveX/RxJS/pull/1244, then I wanted this feature to control openness  in a complexed class dependencies.

+1 Having to write @internal all over the docs is currently my biggest pain point with TS. Which is another way of saying that things are pretty good - good job guys :)

+1
any progress on this?

+1, this would be awesome to have.

This would be really nice for Angular components where you need properties/methods to be public to be accessed by the template, but want them to be private to other users that are consuming your components. The current /** @internal */ feature is problematic because it causes types to fail to satisfy implemented interfaces when the d.ts is compiled downstream.

+1 This would really help with testing; right now you have to make methods public that you really just want to be visible for testing but not part of the public API.

Agreed. This would make sense for services, where you can have internal methods that can only be accessed from other services if necessary, but not the API consumer.

+1 internal modifier would be a big Christmas gift, particularly for TS frameworks construction.

We really need this feature too. I am a developer of a HTML5 engine called Egret. Our engine contains plenty of internal APIs which are not  allowed to accessed by user, otherwise it may cause internal problems. Currently, we have to make them as public and add some documents for it says ' do not use this method! '. It is really hard for us to design a safe and stable engine API because of the lacking of internal . Hope that you could add this feature soon, thanks in advance :)

Hi all，I just found this: http://www.typescriptlang.org/docs/handbook/compiler-options.html , and take a look at the option --stripInternal. It's exactly what we need! I just don't kwon why it is not mentioned in any document. Any way, thanks for add this awesome feature. we gonna use it in our engine right away.

But I think that strip the internal properties or methods away directly may cause some naming problem? For example, if the user creates a subclass and declare a method with the same name to the internal method of the base class. He will not get a error reporting since the internal name is not in the .d.ts file. If I am right, I think the better way to do this is change the modifier to private in the .d.ts instead of stripping the internal method away. But for the @internal above the class, I would like to strip it away,  otherwise, I will need to put lots of  @internal in every method within it.

excuse me, i know what a module or a namespace is, but what is a package?

related https://github.com/Microsoft/TypeScript/issues/321

excuse me, i know what a module or a namespace is, but what is a package?

CommonJS Packages which npm and other JavaScript package managers build upon.

collection of modules, assets etc

looks like something that only makes sense in NodeJS realm

a rigid definition would be a plus

looks like something that only makes sense in NodeJS realm

No, AMD modules are organised into packages, although the AMD loader doesn't read the package.json.  Bower deals with packages and specifically is targeted at a browser context.  It is a pretty well understood concept of a set of modules and other resources (e.g. CSS) that serve a well defined purpose.

a rigid definition would be a plus

The Internet has (sometimes) thrived because of non-rigid definitions.

you might be right about the Internet in general, but this is a

which is a place where rigid definitions are more than welcome

+1 for this. I am currently writing a library that uses builders to construct instances of classes. I have the builder and its target in the same module. The target class should have an internal (or private) constructor because it should only be constructed by the builder. Currently it can't unless I use Reflect to construct the target class. Having a module internal modifier would fix this issue. Would really like to see this in TypeScript.

This is an incredibly useful proposal and, with great respect, I'm a bit surprised it doesn't seem to be getting any love from the dev team, given the number of comments and upvotes.
I need various properties exposed for manipulation by publicly-exported functions that take an instance of a given class and the perform manipulation on members that public to the package, but private to external consumers. The only way to do this currently involves hacks:
The example below is contrived; I'm actually using classes only as minimalistic containers for structural data, but providing a functional interface for manipulation thereof.
export interface MyType {}

export class MyTypeImpl implements MyType {
  constructor(public _k: number) {};
}

// External consumer has no access to the
export function Foo(x: MyType): MyType;
export function Foo(x: MyTypeImpl): MyTypeImpl {
  return new MyTypeImpl(x._k + 1);
}

Alternatively, I could do this:
export function Foo(x: MyType): MyType {
  const y = <MyTypeImpl>x; // but now I'm compiling this pointless variable into my JS output
  return new MyTypeImpl(y._k + 1);
}

Having to use an interface to hide internal members from consumers creates a whole bunch of pointless code throughout my codebase in order to see class internals.

bopping this issue to keep it on the radar, it's important...

Workaround for library authors is to use /** @internal */ on relevant class members in order to stop them from showing up in type definition files.

+1 for this proposal. For current TypeScript, you can use the following code to add internal class to some senerio.
`// This signaure should be defined by other module.
interface Bar {
publicProperty: string;
}
// Signature for using in this module
interface InternalBar extends Bar {
_internalProperty?: string;
}
// Public API
type FooSignature = (obj: Bar, times: number) => void;
// Real Function
const Foo:FooSignature = function (obj: InternalBar, times) {
obj._internalProperty = '1234';
obj.publicProperty = 'test';
times++;
};
export { Foo };`

Is there any news on this? It would be a very much welcomed improvement.

Personally I'm more partial to friend access as you don't have to build multiple times to make use of the feature. It sounds like making something internal to a part of your project would require giving it its own build step.

there is no point of talking about internal (if we come from c# background) until there is a notion of an assembly

If your needs are small, the following example might suffice. It exposes protected properties and methods via a subclass. It has many drawbacks and limitations, but it also has the important pro of avoiding any casts.
Proper support for this feature (or something similar) can't come soon enough!
// For clarity, we define all the "internal" methods and properties here
abstract class InternalWidget {
    protected abstract set internalProperty(value: number);
    protected abstract internalOperation(): void;
}

class Widget extends InternalWidget {
    protected set internalProperty(value: number) {
        console.log("you have the privilege to set this");
    }
    protected internalOperation(): void {
        console.log("you have the privilege to invoke this");
    }
}

// The horrible hack and nasty boilerplate
abstract class InternalWidgetAccessor extends InternalWidget {
    static setInternalProperty(widget: InternalWidgetAccessor, value: number): void {
        widget.internalProperty = value;
    }
    static internalOperation(widget: InternalWidgetAccessor): void {
        widget.internalOperation();
    }
}

// Without
{
    const widget = new Widget();
    widget.internalProperty = 42;   // compiler error
    widget.internalOperation();     // compiler error
}

// With
{
    const widget = new Widget();
    InternalWidgetAccessor.setInternalProperty(widget, 42);  // no error
    InternalWidgetAccessor.internalOperation(widget);        // no error
}

Hope this helps someone out.

I'm not sure if introducing such a complex construct is worth the effort given that this result can already be achieved. The only trade off is to export factories instead of classes (shouldn't you already be doing this anyway?), and then you get a beautiful solution:
export interface ITheClass {
  doStuff(): void;
}

export class TheClass implements ITheClass {

  // === Public API ===

  public doStuff() {
     this.doInternalStuff();
  }

  // === Visible for testing ===

  public doInternalStuff() {

  }
}

Your main export file then looks like this:
// This file is only exporting the public API and a factory method.
// Not only is this solving the problem the `internal` keyword is trying to solve,
// it also ensures I'm hiding implementation and instead only exposing interfaces.

export ITheClass from '...';

export function makeTheClass(): ITheClass {
  return new TheClass();
}

The test code can just new TheClass and get access to the test-only methods, but a user of the package does't see the symbol 'TheClass' and hence can't directly instantiate it.
I'm interested if someone can come up with a use case where the internal keyword would be preferable over the above pattern.

@hmil My main criticisms of your outlined approach are yet-more-boilerplate and inflexibility. In your chosen example, TheClass conveniently has zero constructor arguments. The pattern you are advocating for becomes onerous in code with constructors that (necessarily) take many arguments (and not dictionaries). Additionally, access to the class type is sometimes a requirement. Examples include: use of a framework like Angular where the classes need to be registered for injection, performing instanceof testing, and subclassing.

A factory function can always accept the same arguments as the constructor, which admittedly isn't going to be very DRY.
When you need access to the class itself (for instanceof and such), you can still use the above pattern, just adapt the wording a little. Embed the factory function as a static function of the class and declare the constructor private. You'll need an extra interface to work with this solution.
Here's what you'd get:
export interface ITheClass {
  doStuff(): void;
}

export interface ITheClassTestingInterface extends ITheClass {
  doInternalStuff(): void;
}

export class TheClass implements ITheClass {

  public static create(...args): ITheClass {
    return new TheClass(...args);
  }

  public static createForTesting(...args): ITheClassTestingInterface {
    return new TheClass(...args);
  }

  private constructor(...args) { /* ... */ }

   // === Public API ===

  public doStuff() {
     this.doInternalStuff();
  }

  // === Visible for testing ===

  public doInternalStuff() {

  }
}

This may seem verbose but I would argue that it is worth the extra effort. My point stands: The tools currently available are powerful enough that you can achieve the result but also restrictive enough to enforce good practice (hide your implementations!).
I fear that introducing the internal modifier would just add useless confusion and introduce yet another way for careless developers to screw their packaging (think leaky encapsulation). The exact semantics of the keyword are hard to define (what is a JavaScript "package" anyway?) and maybe harder to understand. The question is: is the above workaround* such a hassle that we want a dedicated keyword just for this manageable use case?
*ps: I don't believe this is a workaround. IMO it's just the right design pattern for the right problem

@hmil Here is a typical constructor from my code base (there are bigger ones than this):
class TheClass {
    constructor(
        private _project: Project,
        private _contextualState: ContextualStateMutator,
        private _flatNavigableTocItems: FlatNavigableTOCItems,
        private _highlightedTokenPosition: HighlightedTokenPosition,
        private _moveSelectedRegions: MoveSelectedRegions,
        private _resizeSelectedRegions: ResizeSelectedRegions,
        private _revealFlatNavigableTocItem: RevealFlatNavigableTOCItemActor,
        private _revealTokenLocality: RevealTokenLocalityActor,
        private _selectTokenLocality: SelectTokenLocality,
        private _selectTokenSpan: SelectTokenSpan,
        private _tokenLabelsMutator: TokenLabelsMutator,
        private _visibleFlatNavigableTocItemMutator: VisibleFlatNavigableTOCItemMutator,
        private _visibleTokenIndexMutator: VisibleTokenIndexMutator,
        private _selectedRegionModels: SelectedRegions,
        private _selectedTokenSpan: SelectedTokenSpan,
    ) { }
}

Implementing your suggested pattern on this class would be insanely verbose, and nicely demonstrates why a new keyword/language feature is so important.

I see how a factory method becomes a problem in your case :smile:  I'm still not convinced there is no other way than the internal keyword though. Consider the following:
The example you gave suggests you are using dependency injection to create TheClass since that is a pretty large amount of arguments for a class you'd construct manually.
In general DI helps with separating implementations from abstractions (that's basically all it does) so it should actually make a case against the internal keyword and not for it. In Java with Guice you would never ever invoke the constructor. Instead there would be something like this somewhere in your code:
bind(ITheClass.class).to(TheClass.class);

Of course we can't do exactly this in TypeScript because interfaces don't materialize in JavaScript. However the DI library you are using has to have a similar way to provide bindings. Which means you could keep the class constructor private and suggest the usage of the interface type rather than the class type.
Although in such situation the user will have access to the "private" API on the class object and will have to remember to only use the interface types from your module. Is it something you are trying to avoid?

@hmil
DI isn't of direct concern to my problem at hand, although I am using it elsewhere for the UI.
 Most importantly, this model is consumed by the rest of the application. Thus, I would like the "behind the scenes" interaction to be obviously marked as such, to be typesafe, and be not too verbose. I would also like the "behind the scenes" interaction to not be plastered all over the public interface of the model.
The consumer of the model (the rest of the app) needs to be using class types. Why?

Because this is a large pre-existing code base and I don't want to go replace all of the instanceof tests with calls to typeguard functions.
Additionally, the model object instances are sometimes injected, and classes are certainly easier than interfaces in that regard.
Plus, I want the type safety that comes with the use of classes (with private ivars), i.e. I want a barrier to forging fake model objects (yes, this is possible with interfaces, but it isn't ideal adding "branding" properties to public interfaces). This is actually quite important as I work in a team of developers spanning the full skill spectrum. Thus it is best if public interfaces only have usefully public things on them, and that developers retain instances of the model objects for later use rather than trying to destruct and reconstruct them later (don't ask).

Basically, I want something akin to Java's package access scope. I don't really care what "package access scope" means in the context of typescript, I'll make it work with whatever we (hopefully) end up with. If it was limited to the current compilation unit (file?) that'd be fine with me. The friend keyword would also do the trick.
Its hard to express the difficultly of working around this language limitation if you've never naturally run against it. Yes, everything can be worked around if you're willing to triple the amount of code you will write and maintain, or if you're willing to have a few points of unsafe casting here or there. Personally, the package access scope feature from Java is sorely missed.

@mark-buer Point made. Thanks for taking the time to explain it in such details.

+1 for the Angular case. Component interfaces are terrible right now and very easy to misuse, especially in testing. An internal modifier would greatly improve things.

+1

I'd like to see this too, but have you guys considered the way Golang handles this? I find their approach quite elegant.
They let you have a directory called /internal, which only allows access to internal modules in the folder containing that internal folder (and from within other internal folders)

@matthewmueller Too easy to mess up. An explicit keyword is much better. You don't need to look where the file is located to understand it's functionality.

@matthewmueller That approach is limited to making an entire module internal or external.  Usually I just want to mark a few members internal.  For example, I have a tree-like structure that has node instances.  The nodes need to be able to muck around with the tree in order to fulfill some of their operations.  Part of the tree's API is internal (to allow the node's pseudo-private access) and part of the tree's API is public.

@rbuckton Is there any status on this? It's been 2.5 years since this was proposed. I'm working on Aurelia vNext right now, completely written in TS. We could really make use of this feature...

As we work on project references, I think we have even more reason to hold off on this. For example, the current proposal relies on a distinction between a declaration in a .ts file and a .d.ts file, but project references heavily leverage .d.ts files.

But is this issue all about preventing definitions of one interface being exported?
We can add a export protected statement that exports one type but disallow accessing its internals with user code (thought the internals are still used by type checking).
protected export interface Engine { ...... }

A protected exported interface (or class' type half) would only outside to see its name and generic parameters (a.k.a. "kind" in FP).

Going to throw my proverbial hat in the ring here, I love internal in C# and would love to see it in TS.  “Pure” encapsulation is nice, but fully decoupling the internals of a program/library is not always practical and then I end up just declaring stuff public when I really would prefer not to.

@DanielRosenwasser Bumping this again since TS is farther down the road after the original project ref work. This does keep coming up in both my open source work and "the day job". I just had a conversation today about how this would be nice to enable certain testing scenarios for our teams, who also don't want the APIs they need for testing exposed to consumers of their APIs, even within the same engineering org. The larger a project/team becomes, I think this sort of things becomes more and more important to have an official solution for, supported by compiler and tooling.

@EisenbergEffect agreed. I've taken to just including a second entry point (e.g. @some-org/somelib/testing) that exposes the "internal" exports as a workaround for this, but something akin to .NET's internal and the internalsVisibleTo attribute would be far more ideal.

@EisenbergEffect does a tool like API Extractor (which @octogonz and others at Microsoft develop) do what you need?
Check out https://api-extractor.com/pages/setup/generating_rollups/#dts-rollup-with-trimming

It's usable for Aurelia, since we ship the APIs officially via npm. However, I'm not sure this works when the context is a larger set of engineers working together to build a unified product, but where the codebase is internally modularized and there are areas of ownership.
To be more concrete, imagine you've got 100 engineers, split into 10 squads of 10 engineers plus a PM each. Each one of those squads then has 3 or 4 sub-squads with 2-3 engineers each. Each sub-squad owns a set of APIs which are consumed by their peers, both inside their squad or outside of it, across the broader team. The sub-squad wants to be able to mark certain things as internal so that they can test them within their own domain, but don't have to worry about one of the other squads using them directly. The area of ownership often manifests as a simple folder within the project, facilitated by GitHub code owners policies. It's not necessarily a formal shipping division, such as an npm package.
Does that help clarify?

@EisenbergEffect I might be missing why the internal modifier would facilitate building protected APIs any more than API Extractor in that organizational structure.

I might be missing why the internal modifier would facilitate building protected APIs any more than API Extractor in that organizational structure.

@DanielRosenwasser if I understood right, he's asking for fine-grained accessibility relationships between individual source files within a project folder.  This is similar to C++ friend classes.  By comparison, API Extractor operates on NPM packages (under the idea that your code base is decomposed into lots of small library packages) -- this is more like C#'s internal keyword that applies to entire .NET DLLs (but all the code within a single DLL has access to all the internals).
For what it's worth, @EisenbergEffect it seems to me that if a collection of files are cohesive enough to be "owned" by a team of people, it might make sense to separate that code into an NPM package.  This approach has worked pretty well for our projects, which frequently have 100+ people working on them.

@octogonz In our case, for various reasons, we can't simply extract 100+ individual packages and shift to a monorepo. It's not that we haven't thought of that and don't want to do it. It's just not possible for this project at this time (and probably for a few years at least). So, I'm looking for ways to work within the current constraints.
All that aside, there is a desire to not have to bring additional tools into play to handle creating an accurate public API and get correct intellisense. So, even with something like API Extractor, it still seems like a work around for language features for which there is precedent elsewhere and which, if incorporated, would result in a better tooling experience.
FYI This isn't a sword I'm willing to die on. It's not a huge issue, more of a nice to have. But, I did want to see where we were at on this, since it seemed like it was being considered, but there was a desire to delay until after TS projects landed.

So, even with something like API Extractor, it still seems like a work around for language features for which there is precedent elsewhere and which, if incorporated, would result in a better tooling experience.

Agreed. It would be better for @internal to be a first class feature of the TypeScript language. (The @alpha/@beta/@public release designations perhaps are more in the province of an external tool.)

If for no other reason than the benefits for testing, I'd still say this is worth doing.  On top of that, my project is also in a similar situation as @EisenbergEffect, where having the ability to control the accessibility on a per-file (or even a per-package, similar to Java) basis would considerably improve the typescript experience for my team.

In my opinion, the whole "internal" thing is related to the need to flatten declarations (#4433).
Both these features imply the fact that there will be an "inside" and an "outside" of the resulting library, usually because of some bundling step that will happen later, after the code is compiled, using tools such as webpack or rollup.
To achieve bundling, one usually has an entry module (index.ts or similar) that re-exports symbols from other modules. The "external" API of the bundled library would then include everything exported, directly or indirectly, from the entry file. That external API is the one that I would expect to see flattened in a single .d.ts file, something that TypeScript is not capable of doing yet.
Exporting the flattened API in that way has two issues and internal would help with both of them.

Keep properties of exported classes from appearing on the API.
To do that manually, one would have to define an interface (exported outside of the library) and a class (kept only inside). This is often too complex for just hiding a couple of methods because they are used for internal communication or for unit testing.
With internal you would just mark methods/properties and the compiler would remove them from the flattened .d.ts. Of course, they are still available at runtime, but a conscious consumer of a TS library should not rely on non-API names. This is no different from how private fields are still accessible at runtime but hidden in the definitions.

Prevent unintentional export of classes
The exported API is the result of a series of re-exports, possibly including full re-exports of intermediate index modules (sometimes called "barrels"). It is easy for a developer to forget about the whole API thing and unintentionally export a top-level name (class, but also function, etc.) that was meant to remain internal.
By marking classes internal the developer would signal his intention to keep that name from appearing on the API. The compiler could then warn about unintentional exports for manual resolution by the developer.

I want to use this so that go can be used by this Checkbox parent class, but cannot be used when accessing Checkbox.OnChecked externally. For now, I am considering this ugly code to be my solution:
type CheckedSignature = (isChecked: boolean) => void;
type InternalCheckedCue = Cue<CheckedSignature>;
type CheckedCue = Pick<InternalCheckedCue, "bind" | "unbind" | "unbindAll">;

class Checkbox {
	/** Fires when the Checkbox is Checked */
	public OnChecked: CheckedCue = new Cue<CheckedSignature>();

	public SetChecked() {
		(this.OnChecked as InternalCheckedCue).go(true);
	}
}

How does one specify which classes/modules/files are able to see a given property?
With my idea over at https://github.com/microsoft/TypeScript/issues/35554, the usage is explicit about what code is allowed to access protected or private members.

I think that internal like in C# (from what I've read, I haven't used C# before) is something that works for C# because the lib can be compiled into an "assembly" -- a grouping of the compiled code, like a DLL or packages in Java.
But in JavaScript/TypeScript, there are no package boundaries, only module (file) boundaries, and NPM package scope is out of question because there are other ways to consume code beside NPM packages, so I think it would be somewhat limiting for internal to apply only within a file.
For example, what if I have code in 5 files that all need to access a private field in the class of a 6th file? It would not be ideal to have to merge the files all into one to achieve the sharing.
So for this to work well in JavaScript/TypeScript, I think we need something that is designed around sharing accessibility explicitly between certain other code in any files, considering that there are no such things as "package" boundaries in JS.
@lorenzodallavecchia You were trying to imagine how a "package" could be defined, above, but as you can tell, it is problematic. We can't prescribe everyone to use a certain form of bundling, or to consider a package to be based on an entry point, or to consider package boundaries to be NPM-style, or etc. End users of any library can import code in many different ways, and can import individual files arbitrarily, not necessarily from any bundle at all, and maybe not even from any sort of package as we know it (for example ES Modules allow us to import files from any URL that can be accessed through the internet and downloaded over HTTP).
I think it may be beneficial to think of methods that would be unique to JS/TS, to explicitly specify shared accessibility with modules or things in modules, like I started to think about in #35554.
What other syntaxes can we use? Can we do it with things other than class members?

Yes @trusktr you have a point in saying that there are possibly multiple concepts of "internal" and "external", With the example of webpack bundling I wanted to present one use case that I think is very common.
It is true that there may be other cases. One may want to declare "internal" scopes within his library just for the sake of encapsulation, without an actual runtime boundary. For example, I miss package-level protection (from Java and Closure) which can only be emulated with poor results using subdirectories in TS.
Even webpack itself can be configured in countless ways, for example splitting the codebase into multiple packages.
TypeScript should ideally have a way of describing the internal/external boundary in all these cases, and I think that is no easy task!
One possible idea is having a form of "scope" declaration that could be used for assigning module files to cross-cutting scopes inside the application. The internal keyword would then refer to the internal side of those scopes. Think of the same as Java package but without the restriction on the directory structure.
But still, I would like to see this feature interact seamlessly with the behavior of bundler, since they are a so common scenario.
And lastly, whatever the solution, I still think that this is somewhat related to API flattening. Simply put, one would want to flatten the API as seen from outside of the outermost boundaries of the library.

Help!
All my helper libraries are cluttered with public _internal_doSomething() methods.
This is ugly.
However, less ugly than calling private methods with bracket notation as mentioned above (which is barbaric).

Given that JavaScript has recently added support private fields, I'm not sure if adding new TypeScript-specific access modifiers is a good call for future proofing the langauge.

I can see how adding new features along the lines of the current access modifiers, which might end up deprecated in favor of native private properties, might be a bad idea. But the need for some well-designed alternative to @internal remains, even if it doesn't look like a new access modifier.

Here is the cleanest workaround I have devised so far:
Type.ts
export class Type {
    protected __shared: number;
    constructor() { }
}

Internal.ts
export interface Type {
    __shared: number;
}

Sample Code
import * as internal from "./Internal.ts"
import Type from "./Type";

let instance = new Type();
(<internal.Type><any>instance).__shared = 1000;

The key is that we need shared properties/methods between classes that are hidden from public APIs
If anyone has an even cleaner typed workaround, let me know.
public is exposed to users through IntelliSense, but protected won't allow enough access, and use of <any> or instance['__shared'] breaks typing.

@jgranick could this approach be modified a bit to use declaration merging? E.g. if Internal.ts was Internal.d.ts, then when the declaration file was used, you'd have access to the internal members. Without it, they're still inaccessible.

I have another thought here. From what I understand, an internal modifier means that method is accessible until it is used by an outsider. But, what is an outsider? I assume we just mean after typescript has built a project. So, what if we had a simple @stripmethod doc comment above methods? Then when typescript declarations are built we remove those methods from the declarations. I think both defining the internal methods and marking them as 'ignored' in declaration files feels like unnecessary complexity. If we simply strip the methods, we might even be able to handle this from outside typescripts compiler.

@andykais If the project is distributed as d.ts then yes, this hides the properties but the properties are still visible in IntelliSense when working with .ts. If you use a common prefix such as "_" then it is sorted before your public members.
I propose that if an internal keyword were adopted, it would behave like /** @internal */ when generating type declarations, public when compiling but protected in IntelliSense hints.

@jgranick By protected do you mean that it will not show up in intellisense?
My preference for internal would be:

Works as public within the project where the code is defined.
Is stripped from all d.ts files.
Is completely invisible outside the TS project where it is defined, regardless of whether it's a TS project that consumes the library directly or something that consumes the d.ts.

Another way I think of it is that it's a normal public property/method/etc in JavaScript. There's no runtime component to this. It's just that it's completely hidden by compiler/intellisense/tooling for any code outside of the project where it is defined.

@EisenbergEffect I would be happy with your proposal if the concept of "inside" or "outside" the project is clear to the compiler. I was concerned this was a foreign concept?
If there is not a way to distinguish cleanly between "inside" or "outside" the project then my proposal might be a second best:

Works as public.
Is stripped from all d.ts files.
Is completely invisible to IntelliSense (or has protected visibility)

I think it's been mentioned elsewhere in this thread, but I would add to @EisenbergEffect's description:

internal classes, functions, variables should be replaceable when aggressively minifying, eg using Closure's ADVANCED_OPTIMIZATIONS .

This is both a way to provide a level of runtime enforcement for internal types/functions/variables, and provides a runtime benefit (smaller names) with no downside. It's also part of the reason that I think internal should be standardized (so tools can use the additional information that it provides).

Just my +1 for internal. I was surprised to find out that Typescript does not support this :(
Another use case to consider, which is specifically mine ;), is having classes share a common abstract parent class. You may want to distribute/document their children, but neither the parent itself nor its methods/properties...

You may want to distribute/document their children, but neither the parent itself nor its methods/properties...

That's simlar to "package protected" as called in other languages. What we need in JS and TS is "module protected" and "module private". Seems that https://github.com/microsoft/TypeScript/issues/35554 would suit your needs more, and it is better than the internal idea here because it limits scope of variables to certain modules, rather than making everything visible in the whole project (protected and private is still valuable within projects, and replacing protected with internal makes them public within a project which is not ideal).

+1 for internal.
I would also like to see this for global functions, variables, etc which also have the export keyword, so that they can be accessed from other files in the same package, including tests (which requires an export declaration,) but 'hidden' externally. The internal keyword would communicate clearly to future maintainers the intent of the associated construct.
On our team, we use the jsDoc /** @internal */ comment quite a lot to designate internal functions, but there are some files that we exclude from the compilation used to generate the index.d.ts file, and in those files, we don't always consistently use the @internal comment (though we probably should.) If someone in the future then does something such that those files are included in the index.d.ts compilation, those functions would be exposed.
An internal keyword with the characteristics described would be especially useful to better communicate intent, and to enforce it as best as Typescript can.

The only time I need to access private methods from the outside would be within a unit test. As we separate the tests from the code how would the "internal" keyword cope with this ?

@Xample Real private methods should not be tested directly, since they are implementation details.
However, it may happen that some methods are "external" from the perspective of a given class, but still "internal" with regard to your libraries. In these cases, it does make sense to test them and this is the exact scenario where the internal keyword would be useful.
So basically you would use internal for all things that are part of the API of a single .ts file, but not part of the API of the overall library that you are building.

Real private methods should not be tested directly, since they are implementation details

Please, see this comment.

Since this seems to go nowhere anytime soon and I am currently in need for this, as I am maintaining a TypeScript Port of a C++ Project (Box2D), which uses C++ friend classes, I need an alternative way to strip away access from the outside.
So I've written a small post-processing tool to help me do this by using recast to transform the (generated) .d.ts files after they've been built. This works by adding a jsdoc tag @internal to your properties, methods and exports.
This is better than stripInternals, since the identifiers still remain in the d.ts files, so they will complain on extended classes, etc. Of course, you'll have the extra work of using jsdoc, but an internal access level would require almost the same amount of work and when the language feature gets implemented, you'll have it easier by just searching for the jsdoc tag and replacing it. Could probably even write a migration tool for that. Doesn't seem to be that much work with recast.
I still need to add these jsdoc tags to my Box2D port, so I haven't tried this on a large scale project yet, but the sample snippets work just fine. Give it a try if you like: https://github.com/Lusito/idtsc
Feel free to add feedback in the project's issue tracker.
Looking forward to a language feature, so I can discontinue this project.

I like this concept of an internal access specifier for the reasons @johncrim indicates because a symbol marked as an "internal detail" can have its face be ripped off and be minified/uglified to death.  That is a pretty nice optimization hint!
I have a separate concern that I feel may have been conflated a bit in the overall discussion above and would like to disambiguate it here.
While TDD'ing code, I will place my *.test.ts unit test files in the same directory as their systems under test, which seems to be a fairly common convention.
I'd like to be able to mark some methods of my class with an access specifier other than public and still have those members be visible within the test module.  JSDoc has this concept, known as package-private:  https://jsdoc.app/tags-package.html
The idea is that modules in the same directory can access the class member as if it was public, but it is private to modules in every other directory.  I like the terminology JSDoc uses for this access specifier, package, so I propose that be what Typescript uses as its keyword unless you have other intents for package.
Finally, this concept differs from #321 where the proposal is for a module access specifier, which is to be module-private.  I imagine that internal could be mixed with access specifiers public, private, protected, package and module.  And if another access specifier is not mixed with internal, public should be the implicit access level as @EisenbergEffect recommends.

still greatly required, we have a multi project solution with TypeScript (using tsconfig project references) and currently we leak all the "should be internal" methods into the other projects, we cannot mark them as private as they are required to be used internally by the project that owns them. internal operating similar to c# would greatly improve the review/maintainability of this codebase and I don't believe I am the only person in this situation otherwise why would TypeScript project references be advertised as a good solution to separate concerns?

+1 for this.

+1 for this as well

I think this would be very helpful +1

While working on a set of cooperating classes, I was looking for the equivalent of C++ friend classes, and stumbled on this  internal proposal. This mechanism is actually much better than friend as it encourages encapsulation at the module level as well as splitting code into small modules of related functionality.

If we simply strip the methods, we might even be able to handle this from outside typescripts compiler.
Wait. Is this solved already? There appears to be a --stripInternal compiler option

The internal modifier would be a syntax sugar for /* @internal */. I think this is the best solution.

While working on a set of cooperating classes, I was looking for the equivalent of C++ friend classes...

I like this possibility too.

There seems to be a ton of discussion on this already, and some work done, but if I'd still be welcome to share my use-case: I have several classes that work together and have methods that they should be allowed to use on each other, but which outsiders should not. Very much like friend in C++. If there was some way of marking classes in the same file or same directory as being allowed to use each other's internal methods, that'd help me clean things up a bit. One idea that would be even more explicit and not require any special file/directory handling, would be if I could mark a specific method/property as being allowed by specific classes, e.g.:
class Bar {
  run(foo: Foo) {
    foo.run() // good
  }
}

class Baz {
  run(foo: Foo) {
    foo.run() // type error
  }
}

class Qux {
  run(foo: Foo) {
    foo.run() // good
  }
}

class Foo {
  internal(Bar, Qux) run() {
    programming.solveOneOffError(n => n+1);
  }
}

Some seem to think this proposal should be exclusive of the friend idea because it assumes only one useful boundary (package level) for visibility control. I say there are two such boundaries. Inappropriate coupling can come from inside a package at least as easily as it can come from outside.
internal would help protect members from inappropriate access from outside a package, but would do nothing to protect them from inappropriate access from within the same package. If anything, people working on a package will naturally encounter more opportunities to misuse access than someone whose only exposure to the package is that they typed npm i and read about the public interface on GitHub.
Now, if your project is 100% yours, or is only worked on by you and other people who understand a unified vision, maybe it makes no difference to you. If that's you, you're very lucky, and I envy you.
In reality, a big organization is going to have a lot of developers who have varying levels of understanding of good architecture, design patterns, etc. Some sleep with the Gang of Four book under their pillows. Others heard of design patterns once three years ago, and... that's it. Therefore, I allege that it's useful to have a mechanism for sharing access to certain things within a subset of a package, but not necessarily to the whole entire package.
For example, suppose you have three layers:

Controller
Service (instantiated by Controller)
Adapter (factoried by Service)

Service has some methods useful both to itself and to Adapter, but which would be inappropriate to be called by Controller. Lacking friend or some substantially similar method, those methods could be made public so that Adapter can call them.
Of course, sooner or later, someone comes along who doesn't understand this design, isn't inclined to learn, and is used to adding conditionals with additional code in the most convenient-looking places. Their behavior is dictated by an energy function which only cares about how many points they can burn down in this sprint. More points = more better! Whatever happens in three months or a year is irrelevant to this energy function.
They tack on some code to Controller which calls methods on Service which were intended for use only by Adapter. This makes perfect sense to them. You know it's going to be harder to maintain this way, but they don't, and whoever reads their PRs won't care either. You can't read every PR organization-wide, and you may not be empowered to decline them anyway. Now a Controller that should be quite thin, and shouldn't be tightly coupled with implementation details at lower levels of abstraction, is hard-wired directly into that stuff.
Possible solutions:
Service "eats" Adapter. Adapter's properties and methods are all moved into Service. What would otherwise have been a concretion of Adapter is now a concretion of Service. This would mash two design patterns together in a way that isn't so great. The resulting class would be much less compliant with the Single Responsibility Principle. What might be just over the edge of "uncomfortably large" today may sprawl into a monstrous God Object by the time a few years have gone by.
The methods/variables you wanted to "friend" could be refactored out to some other class. Service and Adapter would have to extend, implement, or compose with that class. You wouldn't need friend or internal. If you use the extend/implement approach, at least Controller can't mess with those things directly, but then you have to play with inheritance in a way you wouldn't have to with friend or internal. If you use composition instead, then Controller is free to import the class you only wanted to be used by Service and Adapter.
Or... and bear with me here... TS could have both internal and friend.


Do we support multiple responses and exceptions in comments

This is an example of response in swagger: https://github.com/Azure/azure-rest-api-specs/blob/3196a62202976da192d6da86f44b02246ca2aa97/specification/cognitiveservices/data-plane/TranslatorText/preview/v1.0-preview.1/TranslatorBatch.json#L656-L735
In a response there might be several successful responses and exceptions. However, in our current implementation https://github.com/Azure/autorest.csharp/blob/feature%2Fv3/src/AutoRest.CSharp/LowLevel/Output/LowLevelClient.cs#L102-L103, when we generate schema document for , we only take the first response and the first exception. So the response we generate now is like
https://github.com/Azure/autorest.csharp/blob/621093e2bb936b146f73dd49da1047c43e334df9/samples/Azure.AI.DocumentTranslation/Generated/DocumentTranslationClient.cs#L893-L925
And the error response we generate is like
https://github.com/Azure/autorest.csharp/blob/621093e2bb936b146f73dd49da1047c43e334df9/samples/Azure.AI.DocumentTranslation/Generated/DocumentTranslationClient.cs#L903-L917
There is only one response and one error, I don't know how many successful responses we might have in swagger, but at least in swagger there will be multiple exceptions. Do we support multiple successful respones and exceptions if there exists?

@annelo-msft, is it OK to investigate the solution after 1.0 GA?

@pshao25, the examples you're showing come from the DocumentTranslation library which is an HLC in azure-sdk-for-net.  Do we have any examples of multiple responses defined for any of the GA-blocking DPG libraries?

@annelo-msft correct one thing, this swagger generates DP in our autorest repo.
I checked confidentialledger, deviceupdate, webpubsub, and purview. They are not facing this. This should be post-GA issue.

@annelo-msft correct one thing, this swagger generates DPG in our autorest repo.

Yes, I agree that this is correct.  However, since we don't ship a release of the DPG for DocumentTranslation, any issues with the output do not block GA for v1.0.

I checked confidentialledger, deviceupdate, webpubsub, and purview. They are not facing this. This should be post-GA issue.

Agreed.

We won't support this. Close the item.


View Batch Details Page

When I am logged in and click Batch Details on the Sidebar Menu, I want to be able see the View Batch Page.

In order to create the View Batch Page, please check the following component and create new ones if needed:
SideBarMenu (storybook-sidebarnav #38) - MERGED,
Add Batch (Storybook : Initial commit for Add Batch Details #113 ) NOT MERGED YET
Add Image (Storybook: Add Crop Image #7 ) - MERGED
Modal Delete Batch (Storybook: Delete Crop #10) - MERGED
Footer (Feature/footer component refactor #32/Feature/rename footer #52) - MERGED
And consider the DummyPage https://github.com/HackYourFuture-CPH/FP-class11/tree/develop/src/client/containers/batch-detail-page
Make sure that everything is working on all the components and check with the responsible for this issue #107 - Delete batch, and Issue #121 - Get Batch data.

Please consider the SAVE BATCH DETAILS button as a DISABLED button


Progress to low

Required Information
Class: Leatherworker
Level: 71
Craftsmanship: 1744
Control:1557
CP: 468
Recipe Name: Smilodon leather
Recipe Level: 71
Solver Seed: (Look at the top of the Execution Log on the Solver page)
Expected Behaviour
carefull snythesis III should be 573
(Example: Standard Synthesis progress is 42)
Actual Behaviour
Progress is just 426
(Example: Standard Synthesis progress is 38)
Steps To Reproduce
(Example: Buffs, Food, Synthesis Condition, Simulator/Solver Options if different from default)

It looks like this might be a calculation issue, as I'm having a similar miscalculation of progress by a significant margin:
Manasilver Nugget
GSM 70
Craftsmanship sim uses: 1695 (lower to adjust for slight miscalculations)
Simmed Careful Synthesis II progress: 368
Actual craftsmanship: 1698 (higher)
Actual Careful Synthesis II progress: 327
Seed: 100196

Crafter:
  Class: Weaver
  Level: 74
  Craftsmanship: 1695
  Control: 1636
  CP: 400
  Specialist: false

Recipe:
  Level: 403
  Difficulty: 3407
  Durability: 80
  Start Quality: 0
  Max Quality: 16091
  Aspect: none

Settings:
  Max Tricks Uses: 0
  Reliability: 100%
  Use Conditions: true
  Algorithm: eaComplex
  Population: 500
  Generations: 1000
  Penalty Weight: 1000000

It looks like the progress estimates might be off by quite a bit. I'm not looking to hijack, but it looks like the issue I encountered is directly related.
For a different craft, the sim is expecting 368 prog from a Careful Synthesis II, but the actual result in practice is 502 prog. I use a slightly adjusted value for the sim, but I actually use -3 craftsmanship (<1%) to account for miscalculations, but shouldn't result in a difference of 368 v 502.

`Seed: 68948
Crafter:
Class: Weaver
Level: 74
Craftsmanship: 1695
Control: 1636
CP: 400
Specialist: false
Recipe:
Level: 403
Difficulty: 3407
Durability: 80
Start Quality: 0
Max Quality: 16091
Aspect: none
Settings:
Max Tricks Uses: 0
Reliability: 100%
Use Conditions: true
Algorithm: eaComplex
Population: 500
Generations: 1000
Penalty Weight: 1000000`

Post 71 level numbers aren't properly implemented yet so progress will be significantly off. Testers needed to list the following:
Crafter Level:
Recipe Level:
Craftmanship;
Control:
Progress 100% figure in game:
Quality 100% figure in game:
by building up a database of such figures the formulas can be tweaked to give accurate figures. At present it's a catch 22, no figures so not accurate, not accurate without figures.

@ShammyLevva

Ideally a spreadsheet of values. Lots of screenshots would require lots of retyping numbers.

I may take the time to build a sheet as I level to help apply this. Would the recipe level obtained from the Execution Log in the Optimizer under "Level:" be a viable model for recipe level for such a sheet?

The figures entered into the spreadsheet should all be the figures from the game. That way we can double check the simulator matches the game. If they are a hybrid it makes checking trickier.
It is possible for instance that there are mistakes or typos in the sim.

Hi, I've created a quick spreadsheet of all the recipe levels I can currently see ingame (weaver 71-75) and their 100% progress and quality increments vs what is reported on the website.
https://docs.google.com/spreadsheets/d/1skFLa7JcW-VPHyLZzql0qwLBlO6AS0ZRCI-8nfd894Y/edit?usp=sharing

Would it be possible to add the "at 100% efficiency..." info to the simulator screen? If I could see the numbers right there after picking the recipe, preferably where the progress/quality/cp bars are, it would be very quick to whip up a spreadsheet. I'd probably get some numbers for the <70 recipes too, considering the massive amount of people reporting off-by-one progress issues.

@vickyorlo that's the plan.

Hello,
I started a spreadsheet and used values for 70 GSM, 74 LTW, 75 CUL, and 76 WVR at gear, 2 pieces unequipped, and food buffed values. I'll add more as I have more variable levels and gear.
https://docs.google.com/spreadsheets/d/1ismpPPi8tinT88kcVbok1JZ1UfUIxuz5wz61M8dEtR4/edit?usp=sharing

https://docs.google.com/spreadsheets/d/1nxRIA15udQ2cPne9g-bdvp6WPB4peQtj0lyw80G42Wg/edit?usp=sharing
I've taken a slightly different approach and listed for a single crafter for now all the variances between recipes at each level. Thus we can see that for pre 70 levels the sim is pretty much spot on most times for quality but can be considerably out for progress. It is wildly out for post 71 recipes.

Crafter Level: 71 Weaver
Recipe Level: 68
Craftmanship; 1645
Control: 1529
Progress 100% figure in game: 548
Quality 100% figure in game: 595
Optimizer 100% = 266 progress, 297 quality.

We have a new set of formulas for progress and quality increase. These changes are available on the beta site (ffxiv-beta.lokyst.net). Please let me know if these discrepancies are resolved.

The numbers are correct now, I think.  I believe this bug can be closed.

Thanks for confirming.


docs(idempotency): upgrade sample runtime to 3.9

Issue number: #2023
Summary
Improves Idempotency documentation after discussion with @pmarko1711 on Idempotency Record expiration vs DynamoDB TTL expiration.
As I improved it, I've noticed we were light on sequence diagrams to explain common scenarios Idempotency handles it (we can add more later).
Changes

Please provide a summary of what's being changed

[x] Created multiple sub-sections to ease referencing sequence diagrams throughout docs
[x] Added new sequence diagram to demonstrate in-memory cache flow
[x] Added new sequence diagram to demonstrate how we handle records that expired
[x] Added new sequence diagram to demonstrate in-flight requests
[x] revamped timeout sequence diagram
[x] Added idempotency record terminology along with a diagram to explain what's in it (missed that when explaining to Peter how it looks like)
[x] Added new banner to address idempotency record vs DynamoDB Time-to-live (TTL) confusion

Unrelated but sorely needed changes after

[x] Within Choosing a payload subset for idempotency, improved payment scenario by using composite idempotency hash with JMESPath. It's way more realistic and less error-prone to HTTP header change for example.
[x] Hint customers can choose a portion of the payload earlier in the docs

User experience

Please share what the user experience looks like before and after this change

New and revamped sequence diagrams depicting Idempotency Record Status too

New Idempotency Record terminology

Address confusion between Idempotency Record expiration vs DynamoDB time-to-live (TTL)

Adding screenshots shortly
Checklist
If your change doesn't seem to apply, please leave them unchecked.

[x] Meet tenets criteria
[x] I have performed a self-review of this change
[x] Changes have been tested
[x] Changes are documented
[x] PR title follows conventional commit semantics

Is this a breaking change?
RFC issue number:
Checklist:

[ ] Migration process documented
[ ] Implement warnings (if it can live side by side)

Acknowledgment
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.


added time-dependent box size

Fix #361

I backported it to 1.5 (#363), let's merge that instead.

@jkrajniak can you do it in #363?

I ported e33175797598adffc147b16f8fbf95bc17969824 over to #363 already.


impl.md The doc address cannot be accessed

These hyperlinks cannot be accessed

Those article host by blogger which may be need a vpn to access. I can move them to https://juejin.cn/ if you can access this web site.

Those article host by blogger which may be need a vpn to access. I can move them to https://juejin.cn/ if you can access this web site.

Yes, I can visit https://juejin.cn/，thank you


[Docs] Documentation and versioning

Documentation on the react website seems to be from the master version? It is very confusing when developing from the stable version where you expect some things to work but they don't. (renderSeparator for me last week).
There should be some way to browse "older" documentation and most likely it should default to the stable version and not rc.
Food for thought :+1:

This is great but I think Facebook lacks resources on this project somehow.

The docs serve the OSS community and should be driven by us as well.
If you would like to browse the older documentation you can actually just run the server locally very easily - clone the repo and check out the version you are interested in, then cd into the website directory and run node server/server.js - this will start up a docs webserver locally and you can now browse it.
But you're right that it should default to stable and not rc. We discussed this a bit in #1022, @arthuralee perhaps you and @ldesplat can collaborate on coming up with a solution for this?

How about we have the main site pull docs from the version of RN that is on NPM? This would seem to be the correct one.

The main site should match npm, and ideally there would be docs for RC (both to document RC and to act as a staging release in case there's a problem with the docs site) and master. I'm not so familiar with Jekyll and GH pages... is it easy to "reparent" a site so that it could live under https://facebook.github.io/react-native/rc/ or https://facebook.github.io/react-native/master, and customize the CSS a bit to add a banner at the top with the version info?

react-native gh-pages doesn't use jekyll -- there's custom script that downloads the html from the localhost docs server :) it wouldn't be too hard to hack it https://github.com/facebook/react-native/blob/master/website/server/generate.js

I agree that the docs on the site should reflect whats on npm. We do, however, lose the ability to make quick bugfixes to the documentation, as discussed in #1022. I still think a version picker would be very useful in the long term. However, for now, we could just have links to stable, RC, and maybe master.
Yes, the site is generated as @jaredly mentioned, and Travis runs the script (see https://github.com/facebook/react-native/blob/master/.travis.yml#L39-L49). Right now, publish.sh seems to clear out the site and regenerate it. As a starting point we could checkout the latest stable and RC and generate those into subfolders.

@arthuralee :+1: to the version picker

If the new doc generator were to use the git tags (latest stable, latest rc, master) we'd still be able to quickly update the docs in an emergency by overwriting those tags (yay force push) to point to a new commit.

Hi there! This issue is being closed because it has been inactive for a while.
But don't worry, it will live on with ProductPains! Check out it's new home: https://productpains.com/post/react-native/docs-documentation-and-versioning


Delay

Hi olehs,
Why is there 2 seconds delay between receiving information? Can it shorten?
Thx

No, it's hardware issue.

You can shorten delay between readings with setReadTimeout, but this will cause reading errors (-1.0)

Hello olehs,
Thank you for your quick reply !
So like this:
void setup () {
Serial.begin (9600);
pzem.setAddress (ip);
pzem.setReadTimeout (1000); // 1000ms
}
Thx

1000ms is the default timout. You have to decrease it.
PZEM returns 2 readings in 1 second.

Thx olehs
work fine for me
@+

thx olehs
work fine for me
@+


Adapt to new ODP interface

The ODP interface is about to be changed. Information about variables will not be provided as an aggregation, but per drs id. The stores will benefit from that, as it will be clear which dataset will offer which variables.
It is necessary to adapt the store to the changed interface. As we need to prevent that the interface change requires a software change, we must have a software version that works with both interface versions, the new one and the current one.

Solved by #36


Low FPS when with visualisation

The FPS that my Jetson TX2 Outputs fluctuates a lot when I set ‘visualize’ to true in the config.yml file. The FPS drop significantly (down to 7-8FPS from 33-35FPS) when there are many objects present. I was wondering if anyone else experienced this and knew where the bottleneck was occurring.
I changed the object_detection.py script slightly, so that it can use a video as an Input, and the drop in frames does not occur when I set ‘visualize’ to false (in the config.yml).
I understand that visualising the output will reduce the FPS, but I was not expecting it to be so drastic. It would be greatly appreciated if someone could explain why the drop is so drastic or even how to reduce the drop in frames

Hi, Eoinoe
Because camera uses OpenCV but visualization uses PIL.
OpenCV uses numpy array. But PIL cannot use numpy array.
Therefore, visualization need to data convert.
This convert is too slow.
draw_bounding_box_on_image_array() function in visualization_utils.py:
image_pil = Image.fromarray(np.uint8(image)).convert('RGB')
np.copyto(image, np.array(image_pil))

To make matters worse, these are called in visualize_boxes_and_labels_on_image_array() function by object.
performance check:
import numpy as np
import cv2 # for numpy array
import PIL.Image as Image
import time

filename = 'sample300x300.jpg'
print(filename)
image = cv2.imread(filename, cv2.IMREAD_UNCHANGED)
print(type(image))
num_loop = 30 * 20 # 30 FPS with 20 objects

start_time,start_clock = time.time(),time.clock()
for i in range(num_loop):
    image_pil = Image.fromarray(np.uint8(image)).convert('RGB')
    np.copyto(image, np.array(image_pil))
end_time,end_clock = time.time(),time.clock()
print(type(image_pil))
print("PIL convert_from_numpy_array: {:.8f} sec".format(end_time - start_time))

output with 300x300 image size:
sample300x300.jpg
<class 'numpy.ndarray'>
<class 'PIL.Image.Image'>
PIL convert_from_numpy_array: 0.50078821 sec

output with 1280x720 image size:
sample1280x720.jpg
<class 'numpy.ndarray'>
<class 'PIL.Image.Image'>
PIL convert_from_numpy_array: 3.48462892 sec

Image conversion of 300x300 size is processed within 1 second. However, half of the processing time is used for this conversion.
As image size increases, performance degradation appears clearly.
Rewrite PIL to OpenCV in visualization_utils.py, it can be sped up.
I wrote sample code for ssd_mobilenet_v1.

download this code to your object_detection/utils directory.
https://github.com/naisy/realtime_object_detection/blob/master/object_detection/utils/visualization_utils_cv2.py
edit your object_detection.py
before:
 from object_detection.utils import visualization_utils as vis_util
after:
 from object_detection.utils import visualization_utils_cv2 as vis_util
run object_detection.py

Note:

OpenCV cannot use custom font. Therefore, the font is not beautiful.
PIL: font = ImageFont.truetype('arial.ttf', 24)
OpenCV: fontFace = cv2.FONT_HERSHEY_SIMPLEX
visualization_utils_cv2.py is not completed. This works only ssd_mobilenet_v1.

@naisy again great work! Would you mind filing a Pull Request i would very much like to include this feature!
ANother question: Does your multi-processing show performance increase? Has it better results than multi threading?

Hi, @GustavZ,
I added the following two functions.
def draw_bounding_box_on_image_cv ()
def draw_bounding_box_on_image_array_cv ()

By searching with _cv you will find the fixes.
I deleted the following two functions.
def draw_bounding_box_on_image ()
def draw_bounding_box_on_image_array ()

Also, I changed the color definition for OpenCV.
STANDARD_COLORS = [...
I didn't fix next three functions.
def draw_mask_on_image_array ()
def draw_keypoints_on_image_array ()
def draw_keypoints_on_image ()

If this code runs on other models, it will need to modify these functions.

My multi-processing code is bad performance than multi-threading.
I tried the following three methods to pass the image data to the process.

multiprocessing.Pipe()
multiprocessing.Manager().dict()
multiprocessing.Manager().Queue()

The fastest one is Pipe(). But that is slower than multi-threading.

Certainly yml has more code in multi-processing.
It leads careless mistakes.
But in the case of yml, I think that it is a easy way to edit parameters. Because it can without changing the python code.
Therefore, I think it is good idea to modify parameters with yml and prepare a class to load it.

Loading the class with yml somehow does not work for me

alright, now i have the config class plus the yaml file.
Also openCV Mask drawing besides your modified vis_util functions!
have a try :)

Hi @GustavZ,
Nice! v2.0's both run_objectdetection.py and run_deeplab.py worked!
But.. v2.0 is a little bit slow down than v1.0.
Specifically, object_detection.py (v1.0) of 1280 x 720 is 27-28 FPS, but run_objectDetection.py (v2.0) of 1280 x 720 is 25-26 FPS.
This seems to be slow regardless of visualization.
How about in your environment?

@naisy  Yeah i face similar results.
I dont know why there is a performance loss :/ maybe you have some pythonic insights?
Another point:
Currently i am drawing the masks with openCV like that:
  mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2RGB)
  mask[np.where((mask == [1,1,1]).all(axis = 2))] = color
  cv2.addWeighted(mask,alpha,image,1-alpha,0,image)

The Problem is that this correctly draws the colored masks, but darkens everything around the mask, so if you have several objects on the input image, everything gets nearly black.
Do you have an idea how to solve this corretcly?
As info The mask is a Binary (1,0) Numpy array with the same size as the image,but lacking the color channels (so they need to be created)
I tried it with
mask =  numpy.expand_dims(mask, 2)
mask = numpy.repeat(mask, 3, axis=2)

Instead of the cvtColor function, but i has the same effect.

Hi @GustavZ,
I saw run_deeplab.py.
before:
cv2.addWeighted(seg_image, config.ALPHA, frame, 1-config.ALPHA, 0, frame)

after:
cv2.addWeighted(seg_image, config.ALPHA, frame, 1.0, 0, frame)

before's background seems dark. maybe this?
And about color making,
before:
seg_image = create_colormap(seg_map).astype(np.uint8)
this part is not bad, but next is more clear and better performance.
after:
seg_image = STANDARD_COLORS[seg_map]
STANDARD_COLORS
STANDARD_COLORS = np.array([
    (0, 0, 0), # Blank color for background
    (0, 255, 255), # Yellow
    (0, 140, 255), # DarkOrange
    (139, 139, 0), # DarkCyan
    (11, 134, 184), # DarkGoldenRod
    (169, 169, 169), # DarkGrey
    (107, 183, 189), # DarkKhaki
    (211, 0, 148), # DarkViolet
    (238, 130, 238), # Violet
    (0, 128, 128), # Olive
    (122, 150, 233), # DarkSalmon
    (147, 20, 255), # DeepPink
    (204, 50, 153), # DarkOrchid
    (143, 188, 143), # DarkSeaGreen
    (255, 255, 0), # Cyan
    (209, 206, 0), # DarkTurquoise
    (255, 191, 0), # DeepSkyBlue
    (255, 144, 30), # DodgerBlue
    (34, 34, 178), # FireBrick
    (0, 215, 255), # Gold
]).astype(np.uint8)

color time before: 0.01716923713684082
color time after: 0.009123802185058594

Because color definition can be done for each label in STANDARD_COLORS, I think that it is easy to understand.

Thanks for the hints! Very useful as always @naisy 👍

Yes! Need 20+1!
Thank you!


Interfaces are implemented implicitly

Context: https://tour.golang.org/methods/10
Normalize names.
package main

import "fmt"

type Speaker interface {
	Speak()
}

type Cat struct {
	Greeting string
}

func (c Cat) Speak() {
	fmt.Println(c.Greeting)
}

func main() {
	var animal Speaker = Cat{"meow"}
	animal.Speak()
}

Are you suggesting that the tour code be improved to be more understandable to newcomers?

Yes
Sent from my iPhone

On 09 Aug 2017, at 08:18, Daniel Martí<EMAIL_ADDRESS>wrote:
Are you suggesting that the tour code be improved to be more understandable to newcomers?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.

I believe the previous page could also be improved. While it makes sense now I know what interfaces are, I had to Google and find this resource to reach that point.
Of course we can't line up the information on the left to reflect the code, but we could move the information into comments, or style the steps similarly to the left hand side of Mutating Maps.
With these changes, we may not need a separate page on "Interfaces are implemented implicitly". If we wanted to keep it though, we could use the same code we use on "Interfaces", just with a couple of comments to highlight the point.

If this issue is about using more verbose names in this page of the tour instead of I and M I am totally in. Abbreviation and one letter names are really confusing here to newcomers.


Make a docset for Dash

Here's a great offline API browser: http://kapeli.com/dash
It would be really great to always have SugarJS API in Dash.

Thanks for this issue (about a billion years later). Work on Sugar was stagnating a bit, but v2.0.0 is soon to be released. There's a lot of changes that have to be made to the site's docs, but I've made a note that after everything is released to go back and look at Dash. It looks like I can easily generate the docset from the HTML source so I'll probably have a look at doing it that way.
Going to close this issue out for now. Thanks!


Support FD passing

Currently, requests and replies with FDs result in invocations of unimplemented!(). This is certainly improvable. :-)
No idea what to do on Windows (does libxcb even support FD passing on Windows?), but on Unix-like platforms, std::os::unix::io::AsRawFd can be used for requests and std::os::unix::io::RawFd for replies. However, we need some "owning" kind of raw fd, so additionally some wrapper like libc::dup is needed.
This requires some API design that makes it hard to leak FDs. Do replies own the contained FDs and close them when drop()d?

Fixed by #79 and #85


Add Prisma Client Python

https://github.com/RobertCraigie/prisma-client-py
These benchmarks would probably be very similar to the existing Prisma benchmarks but it would be helpful for me to see how it compares to other Python ORMs.
I'd be happy to implement this myself, just wanted to open an issue beforehand :)

Feel free to contribute a PR :)

Would love to see to this!


Pull FetchRequestController out into a separate pod.

I'd like for FetchRequestController and FetchRequestControllerDelegate to be moved into a separate pod.
This is a really useful abstraction of NSFetchedResultsController into Swift with generics, and I think people should be able to use it without depending on the entire AlecrimCoreData pod.
I'm interested in creating a generic subclass of FetchRequestController that allows you to map your NSManagedObjects into other objects to better support dependency inversion for view controllers. I think this subclass would be a perfect fit for a new FetchRequestController pod, but it doesn't make sense for this all to be packaged tightly with AlecrimCoreData.
Thoughts?

Hello. I think that FetchRequestController related features are very suitable to be moved to other project (pod or SPM package) but I do not know if this will be possible to be done in the next release. I’m working to add “independente data sources” support (with them one Table/Collection view will be able to have several bound fetch request controllers, each of them handling their own index paths and cells). This is other set of features that would be nice to be in other project with ACD as dependency.

I don't see why this can't be pulled out for the next release. It shouldn't take long to create a new pod with these features in it and a dependency on ACD. Is there any reason why the next release would require these features to be included?


Improve the output of docker-machine ls in case of an error

docker-machine ls prints something like this in case one of the machines is not well configured.
$ docker-machine ls

error getting URL for host other: machine does not exist
error getting state for host other: machine does not exist
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM
default   -        virtualbox   Running   tcp://<IP_ADDRESS>:2376
other     -        virtualbox   Error

The problem occurs for example when a machine is manually deleted.
It would be nicer for the user either swallow the error or move the message to an additional column, like this:
$ docker-machine ls

NAME      ACTIVE   DRIVER       STATE     URL                         SWARM ERRORS
default   -        virtualbox   Running   tcp://<IP_ADDRESS>:2376
other     -        virtualbox   Error                                       machine does not exist

Huge +1 from my end on this, it's been a pet peeve for a long time.
How I would like to do this is to move over to per-driver loggers (consequently things logged within the driver would be query-able later using docker-machine logs) which can also be accessed externally using a driver.Log method.  Unfortunately, though, we can't write code that depends on that once we start distributing plugins everywhere (very soon) which don't have it (without a version bump to the plugin API, at least).
Maybe we can instead aggregate the external errors (notice that the kind you list above come from outside the driver, not inside) and display them in an error column like you mention.

@nathanleclaire Let's start with the aggregation. Ok ?

Yeah that SGTM


webclient tests no longer work from travis

Since around the new year, the webclient tests have been tripping Google's ATO detection. I don't see an easy way around this in the account settings: turning off various protections and accepting the logins as mine don't seem to make a difference.
I'm just going to turn off the webclient tests in CI for now.

There's no need for these anymore.


[Feature Request] Client/Server Mode

Reference: https://docs.trychroma.com/usage-guide#running-chroma-in-clientserver-mode

Will be solved with #117

Solved by #220


feat(cli): show descriptor discrepancies in non-interactive mode

Ensure the CLI exits with exitcode 1 when there are discrepancies between descriptors found in the JSON and descriptors generated from the metadata. Integration test added to ensure this works.

wait i gotta make sure it crashes for all that fail rather than first one :)


Use the latest autorest libraries for type generation

This PR contains the code changes to switch from C# type generation to TypeScript.
The motivation is that the library we're using (https://github.com/Azure/autorest.common) is not being actively maintained, with modern extensions being authored using https://github.com/Azure/autorest/tree/master/packages/extensions/modelerfour

Codecov Report

Merging #146 (8c0bb14) into main (272eee0) will increase coverage by 1.58%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main     #146      +/-   ##
==========================================
+ Coverage   93.65%   95.23%   +1.58%
==========================================
  Files          17       17
  Lines         252      252
==========================================
+ Hits          236      240       +4
+ Misses         16       12       -4

Flag
Coverage Δ

dotnet
95.23% <100.00%> (+1.58%)
:arrow_up:

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files
Coverage Δ

src/Bicep.Types/TypeSerializer.cs
100.00% <ø> (+20.00%)
:arrow_up:

src/Bicep.Types.Az/Index/TypeIndexer.cs
100.00% <100.00%> (ø)

Does running the new generator on the same commit as the old one produce an empty diff or a diff with "good" changes?

Does running the new generator on the same commit as the old one produce an empty diff or a diff with "good" changes?

Yes - I used the diffs heavily to progressively work towards this implementation. I spent some time going through the final product and coudln't find anything major other than naming and formatting differences.


Add configuration for the stale bot

As mentioned in this commit we'd like to close issues after 30 days. @gep13 suggested to automate this using the stale bot.
@Petermarcu @richlander  @jongalloway: any concerns?

As already mentioned on Twitter I think this is a bad idea for the announcements repo.
It'll result in constant "issue closed" notifications which is the exact opposite of what I want from watching this repo. In addition it'll touch the last updated date of the issue which makes it useless for knowing when a real update happened. Issues in the announcements repo are naturally ordered by design already.
I don't see how this will result in a more manageable issue list, most people don't look at page 2 anyway. It could even make it worse since they'd only look at the open issues and miss important stuff that happened 31 days ago.
ASP.NET keeps their announcements open forever (they only close invalid ones or where the plan changed), which I think is ideal.
/cc @NickCraver @benadams who seemed to have the same opinion on Twitter.

I think that logic makes sense in repo's who's entire purpose is announcements (like this one). When we put announcements in other repo's for one reason or another, we shouldn't keep them open forever because we do use those other repos to track and manage non-announcement issues.

Exactly, the announcements repo is a special case. The linked discussion threads in other repos can be closed based on normal rules.
Btw. I just followed the "Breaking Changes" link in https://github.com/dotnet/announcements#using-the-issues-list and the list came back empty. Because they are hidden in the closed issues tab 😄

I agree with @akoeplinger it is more an annoyance to receive a notification for a closed announcement (which doesn't bring any relevant semantic value). I don't see much trouble leaving the announcements as opened issues in github.

I also agree with @akoeplinger, @Petermarcu, & @xoofx... the only thing closing announcements does is muck with dates & generate extra emails that no one wants to see anyway.  Manageability is a non-issue in a repo with no code & builds/deployments.

Maybe it makes sense to open & close them in one go?
I agree that an email 30 days later somehow confuses people, but keeping them open is not good either.

Why is keeping them open not good?
On Fri, 10 Nov 2017, 14:13 Robin Krom<EMAIL_ADDRESS>wrote:

Maybe it makes sense to open & close them in one go?
I agree that an email 30 days later somehow confuses people, but keeping
them open is not good either.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/announcements/pull/42#issuecomment-343483706,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AApXSDm-xb3ef-_bYSaG3JBQ_QcQn5Wpks5s1FoHgaJpZM4QYzkl
.

All I want is a single email when there's an announcement. If that's not going to be possible on GitHub, can we get a mailing list instead? Is there already one I can join?
The other .NET related announcement repos do this right and only create (and rarely/never modify or close) issues. I don't see why this one needs to be different.
Thanks though for disseminating the information, and sorry to be cranky about it.

See #43. Based on your feedback, we've decided not to close issues.

AAAAAAAAAAAAA! STOP SPAMMING! @terrajobst

Agreed. I'm subscribed to this repo for notifications. Not spam. Please
revert to previous behaviour.
On 10 Nov 2017 10:08 p.m., "Vitaly Zilnik"<EMAIL_ADDRESS>wrote:

AAAAAAAAAAAAA! STOP SPAMMING! @terrajobst https://github.com/terrajobst
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/announcements/pull/42#issuecomment-343600128,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AB0YWuWF3c--TswyNGLS9UkTHYtEr4JFks5s1MlMgaJpZM4QYzkl
.

we've decided not to close issues
And decided to REOPEN all the issues?? And even post a comment in each of those???
Genius!
Two more emails per each issue.
Guess I'm going back to RSS...

The problem is not the reopening of the issues. The problem is the decision that was made 4 days ago to close these issues in the first place. That was recognised and accepted as a bad decision. After that was recognised, the team were left with, essentially, three options:

Double-down on the original decision and keep closing issues because "it's too late to change now" - this would have led to double notifications for all issues for eternity
Reverse the decision and revert back to the previous process (leaving all issues open), but leave the closed issues closed. - this would leave the repo in "partial" state of correctness with some issues open and some closed, for no good reason, and would no doubt result in future confusion and questions about what is different about the closed issues, "are the announcemnts invalid?", "are they wrong?", etc.
Reverse the decision, revert to the previous process, and re-open the closed issues.

I believe the team did exactly the right thing by choosing option 3, and I also believe it's a good idea to put a comment on each issue explaining why it has been reopened. For anyone not subscribed to this conversation, reopening without a comment could also cause confusion and raise questions, e.g. "why has this been reopened?", "has it changed?". etc.
Yes, there's a bit of pain for us subscribers right now as we get these notifications all over again, but it's over now, and the delete key is your friend. Yes, it's unfortunate that the team made the decision 4 days ago to close those issues, but I'm glad they recognised that and took corrective action. We are now back to where we were originally. We'll only receive notifications for new announcements, and we can put this whole episode behind us.


Fix SyntaxError: Illegal return statement

Faced with SyntaxError in this package, because some package in my project depend from this package.

https://github.com/inspect-js/is-set/pull/4#pullrequestreview-332658947


secret switch scene

label .eating:
    scene bg museum_food
    show eating
    show posty neutral
    if food_switch == False:
        p "_" # posty observes that the painting doesn't really belong here. these are paintings of food, not paintings of eating. she takes a look at the painting's placard, curious why it was included.
        "The title of the painting is \"{i}Crisis of the Poplar Trees{/i}\". The rest of the text is too small to read at this distance."
        p "_" # posty remarks that that's hardly a fitting name for this painting either, and it sure as hell isnt fitting for a painting in the food exhibit.
        label .eating_decide:
        menu:
            "Read more of the placard?"

            "Yes.":
                "You try to read more of the placard, but bonk your face on it by mistake!"
                # play a sound here! like a click!!!
                # and then a scene of the corndog painting disappearing, revealing the secret passageway.
                $ food_switch = True
                p "_" # something like "well that was weird. better back off"
                jump museum_food
            "No.":
                p "_" # posty decides she is uninterested in reading more of the placard. she starts to walk away, but returns to the placard, still curious.
                jump .eating_decide
    else:
        p "_" # posty returns to actually read the placard this time.
        "The placard reads: \"{i}(something){/i}\". Weird!" # placard full text.
        p "_" # some kind of remark
        jump museum_food

the secret passage opening will be produced after imagemaps are implemented

p suspicious "Huh what is that doing there? Among all the food based pieces, it doesn't look that appetizing to look at someone eating."
"The title of the painting is "{i}Crisis of the Poplar Trees{/i}". The rest of the text is too small to read at this distance."
p "The only thing true about the title is that guy is clearly having a crisis about something!"
p "If I didn't know any better, I would've thought he was having some pizza psychosis..."
Yes
p astonished "Ooh sneaky!"
p neutral "..."
p concerned "Better step away and pretend nothing ever happened-"
p "Doodly doo do dooo just a postbox walking away from a mysterious hole in the ground in an innocent waaay!"

p "There are a lot of people in here who are... well connected to say the least."
p "Better not interfere with affairs I don't know of!"
p neutral "..."
p concerned "But on the other hand, this painting really draws me in."
p "I know I shouldn't poke around, buuuutt then I would have to deal with not knowing why this piece exists."
p "Who is this guy? Why does he have a slice? Where is he being kept? Who painted this? Why is he angry? Did the painter survive and if so, where can I find them? Why why why why-"
p zany "Damn just thinking about this drives me NUTS!"

added some of this. the rest needs to be replaced to better match the context of the scene


Bump fixed-mode-hide-chat

This updates the "Hotkey used to toggle hiding the chat" config key name, which will make people lose their configs. You might want to revert that key change back to hideChatHotkey

Is renaming the config key worth it, since it'll be wiping the value?
Additionally, will this consume everyone's escape key by default? Maybe that will cause some support traffic since it's often used to close the bank or to swap tabs.
Finally, it's replacing the hide chat option with a toggle. Maybe people will complain that the old behaviour is gone, but that's a decision you have to make yourself.

The config rename doesnt matter and it doesnt consume escape key (as it would also need to consume it in the other handlers i guess). But the current behaviour is kinda annoying as it both closes a bank and the chat at once so /shrug

Yea I think the new behaviour is too annoying so just gonna revert it.


add worker's queues to $0

As my use-case is to take advantage of having multiple queues and dedicating workers with overlapping coverage of them (to ensure that jobs in the high_priority queue have more workers servicing them, but that low_priority jobs aren't completely starved out), I'd really like to know which workers are handling which queues. This change makes that easy to see from just the ps output (or from pgrep -fal delayed_job)

Coverage decreased (-0.2%) to 90.95% when pulling b46a145e6d981ebb5f562617cefc7b54010ca0d7 on scrumalliance:master into 71f1d5faf934d3057abca942f0d410327bc69087 on collectiveidea:master.

Coverage increased (+0.008%) to 91.129% when pulling a02cf9a3e9c23ca82dcf9fbbbfc9a0f1c8697e58 on scrumalliance:master into 71f1d5faf934d3057abca942f0d410327bc69087 on collectiveidea:master.

Coverage increased (+0.008%) to 91.208% when pulling d4ed3e176a5919eb3523c33fa02d076ebbb19c73 on scrumalliance:master into 1e679174b513dc711f7d764c8bd9d4f5c6495276 on collectiveidea:master.